all: add support for zos/s390x
This adds net support for zos/s390x. These changes should not affect other platforms.
Fixes golang/go#42130
Change-Id: Ia7faa29de76b7c5713120657b296106c2e27bfd2
Reviewed-on: https://go-review.googlesource.com/c/net/+/264028
Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
Trust: Tobias Klauser <tobias.klauser@gmail.com>
Trust: Emmanuel Odeke <emmanuel@orijtech.com>
diff --git a/http2/server_test.go b/http2/server_test.go
index 0a50729..7f644d4 100644
--- a/http2/server_test.go
+++ b/http2/server_test.go
@@ -1189,10 +1189,9 @@
}
func TestServer_RejectsLargeFrames(t *testing.T) {
- if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
+ if runtime.GOOS == "windows" || runtime.GOOS == "plan9" || runtime.GOOS == "zos" {
t.Skip("see golang.org/issue/13434, golang.org/issue/37321")
}
-
st := newServerTester(t, nil)
defer st.Close()
st.greet()
diff --git a/internal/socket/cmsghdr.go b/internal/socket/cmsghdr.go
index 0a73e27..0cde35a 100644
--- a/internal/socket/cmsghdr.go
+++ b/internal/socket/cmsghdr.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package socket
diff --git a/internal/socket/cmsghdr_stub.go b/internal/socket/cmsghdr_stub.go
index 8328b7d..83c35ec 100644
--- a/internal/socket/cmsghdr_stub.go
+++ b/internal/socket/cmsghdr_stub.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package socket
diff --git a/internal/socket/cmsghdr_zos_s390x.go b/internal/socket/cmsghdr_zos_s390x.go
new file mode 100644
index 0000000..98be146
--- /dev/null
+++ b/internal/socket/cmsghdr_zos_s390x.go
@@ -0,0 +1,25 @@
+// Copyright 2020 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 socket
+
+import "syscall"
+
+func (h *cmsghdr) set(l, lvl, typ int) {
+ h.Len = int32(l)
+ h.Level = int32(lvl)
+ h.Type = int32(typ)
+}
+
+func controlHeaderLen() int {
+ return syscall.CmsgLen(0)
+}
+
+func controlMessageLen(dataLen int) int {
+ return syscall.CmsgLen(dataLen)
+}
+
+func controlMessageSpace(dataLen int) int {
+ return syscall.CmsgSpace(dataLen)
+}
diff --git a/internal/socket/error_unix.go b/internal/socket/error_unix.go
index f14872d..47f0d6e 100644
--- a/internal/socket/error_unix.go
+++ b/internal/socket/error_unix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package socket
diff --git a/internal/socket/iovec_64bit.go b/internal/socket/iovec_64bit.go
index dfeda75..0309e10 100644
--- a/internal/socket/iovec_64bit.go
+++ b/internal/socket/iovec_64bit.go
@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// +build arm64 amd64 ppc64 ppc64le mips64 mips64le riscv64 s390x
-// +build aix darwin dragonfly freebsd linux netbsd openbsd
+// +build aix darwin dragonfly freebsd linux netbsd openbsd zos
package socket
diff --git a/internal/socket/iovec_stub.go b/internal/socket/iovec_stub.go
index a746e90..f44d4f5 100644
--- a/internal/socket/iovec_stub.go
+++ b/internal/socket/iovec_stub.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package socket
diff --git a/internal/socket/msghdr_stub.go b/internal/socket/msghdr_stub.go
index 873490a..1a253d2 100644
--- a/internal/socket/msghdr_stub.go
+++ b/internal/socket/msghdr_stub.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package socket
diff --git a/internal/socket/msghdr_zos_s390x.go b/internal/socket/msghdr_zos_s390x.go
new file mode 100644
index 0000000..eb1a99a
--- /dev/null
+++ b/internal/socket/msghdr_zos_s390x.go
@@ -0,0 +1,36 @@
+// Copyright 2020 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 s390x
+// +build zos
+
+package socket
+
+import "unsafe"
+
+func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
+ for i := range vs {
+ vs[i].set(bs[i])
+ }
+ if len(vs) > 0 {
+ h.Iov = &vs[0]
+ h.Iovlen = int32(len(vs))
+ }
+ if len(oob) > 0 {
+ h.Control = (*byte)(unsafe.Pointer(&oob[0]))
+ h.Controllen = uint32(len(oob))
+ }
+ if sa != nil {
+ h.Name = (*byte)(unsafe.Pointer(&sa[0]))
+ h.Namelen = uint32(len(sa))
+ }
+}
+
+func (h *msghdr) controllen() int {
+ return int(h.Controllen)
+}
+
+func (h *msghdr) flags() int {
+ return int(h.Flags)
+}
diff --git a/internal/socket/rawconn_msg.go b/internal/socket/rawconn_msg.go
index d5ae3f8..610b1a1 100644
--- a/internal/socket/rawconn_msg.go
+++ b/internal/socket/rawconn_msg.go
@@ -2,12 +2,13 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package socket
import (
"os"
+ "runtime"
"syscall"
)
@@ -24,7 +25,7 @@
var n int
fn := func(s uintptr) bool {
n, operr = recvmsg(s, &h, flags)
- if operr == syscall.EAGAIN {
+ if operr == syscall.EAGAIN || (runtime.GOOS == "zos" && operr == syscall.EWOULDBLOCK) {
return false
}
return true
@@ -61,7 +62,7 @@
var n int
fn := func(s uintptr) bool {
n, operr = sendmsg(s, &h, flags)
- if operr == syscall.EAGAIN {
+ if operr == syscall.EAGAIN || (runtime.GOOS == "zos" && operr == syscall.EWOULDBLOCK) {
return false
}
return true
diff --git a/internal/socket/rawconn_nomsg.go b/internal/socket/rawconn_nomsg.go
index b8cea6f..e51b60d 100644
--- a/internal/socket/rawconn_nomsg.go
+++ b/internal/socket/rawconn_nomsg.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package socket
diff --git a/internal/socket/socket_test.go b/internal/socket/socket_test.go
index 038e8e9..8952c22 100644
--- a/internal/socket/socket_test.go
+++ b/internal/socket/socket_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package socket_test
diff --git a/internal/socket/sys_const_zos.go b/internal/socket/sys_const_zos.go
new file mode 100644
index 0000000..01b6372
--- /dev/null
+++ b/internal/socket/sys_const_zos.go
@@ -0,0 +1,17 @@
+// Copyright 2020 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 zos
+
+package socket
+
+import "syscall"
+
+const (
+ sysAF_UNSPEC = syscall.AF_UNSPEC
+ sysAF_INET = syscall.AF_INET
+ sysAF_INET6 = syscall.AF_INET6
+
+ sysSOCK_RAW = syscall.SOCK_RAW
+)
diff --git a/internal/socket/sys_posix.go b/internal/socket/sys_posix.go
index 22eae80..05ded23 100644
--- a/internal/socket/sys_posix.go
+++ b/internal/socket/sys_posix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package socket
diff --git a/internal/socket/sys_stub.go b/internal/socket/sys_stub.go
index 8e1e074..3c97008 100644
--- a/internal/socket/sys_stub.go
+++ b/internal/socket/sys_stub.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package socket
diff --git a/internal/socket/sys_zos_s390x.go b/internal/socket/sys_zos_s390x.go
new file mode 100644
index 0000000..1e38b92
--- /dev/null
+++ b/internal/socket/sys_zos_s390x.go
@@ -0,0 +1,38 @@
+// Copyright 2020 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 socket
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
+func syscall_syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
+func probeProtocolStack() int {
+ return 4 // sizeof(int) on GOOS=zos GOARCH=s390x
+}
+
+func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
+ l := uint32(len(b))
+ _, _, errno := syscall_syscall6(syscall.SYS_GETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0)
+ return int(l), errnoErr(errno)
+}
+
+func setsockopt(s uintptr, level, name int, b []byte) error {
+ _, _, errno := syscall_syscall6(syscall.SYS_SETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0)
+ return errnoErr(errno)
+}
+
+func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
+ n, _, errno := syscall_syscall(syscall.SYS___RECVMSG_A, s, uintptr(unsafe.Pointer(h)), uintptr(flags))
+ return int(n), errnoErr(errno)
+}
+
+func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
+ n, _, errno := syscall_syscall(syscall.SYS___SENDMSG_A, s, uintptr(unsafe.Pointer(h)), uintptr(flags))
+ return int(n), errnoErr(errno)
+}
diff --git a/internal/socket/sys_zos_s390x.s b/internal/socket/sys_zos_s390x.s
new file mode 100644
index 0000000..60d5839
--- /dev/null
+++ b/internal/socket/sys_zos_s390x.s
@@ -0,0 +1,11 @@
+// Copyright 2020 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 ·syscall_syscall(SB),NOSPLIT,$0
+ JMP syscall·_syscall(SB)
+
+TEXT ·syscall_syscall6(SB),NOSPLIT,$0
+ JMP syscall·_syscall6(SB)
diff --git a/internal/socket/zsys_zos_s390x.go b/internal/socket/zsys_zos_s390x.go
new file mode 100644
index 0000000..514ca37
--- /dev/null
+++ b/internal/socket/zsys_zos_s390x.go
@@ -0,0 +1,32 @@
+// Copyright 2020 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 socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Iov *iovec
+ Control *byte
+ Flags int32
+ Namelen uint32
+ Iovlen int32
+ Controllen uint32
+}
+
+type cmsghdr struct {
+ Len int32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofCmsghdr = 12
+ sizeofSockaddrInet = 16
+ sizeofSockaddrInet6 = 28
+)
diff --git a/ipv4/control_stub.go b/ipv4/control_stub.go
index a0c049d..9d82534 100644
--- a/ipv4/control_stub.go
+++ b/ipv4/control_stub.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv4
diff --git a/ipv4/control_zos.go b/ipv4/control_zos.go
new file mode 100644
index 0000000..0442000
--- /dev/null
+++ b/ipv4/control_zos.go
@@ -0,0 +1,86 @@
+// Copyright 2020 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"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+)
+
+func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
+ m := socket.ControlMessage(b)
+ m.MarshalHeader(iana.ProtocolIP, sysIP_PKTINFO, sizeofInetPktinfo)
+ if cm != nil {
+ pi := (*inetPktinfo)(unsafe.Pointer(&m.Data(sizeofInetPktinfo)[0]))
+ if ip := cm.Src.To4(); ip != nil {
+ copy(pi.Addr[:], ip)
+ }
+ if cm.IfIndex > 0 {
+ pi.setIfindex(cm.IfIndex)
+ }
+ }
+ return m.Next(sizeofInetPktinfo)
+}
+
+func parsePacketInfo(cm *ControlMessage, b []byte) {
+ pi := (*inetPktinfo)(unsafe.Pointer(&b[0]))
+ cm.IfIndex = int(pi.Ifindex)
+ if len(cm.Dst) < net.IPv4len {
+ cm.Dst = make(net.IP, net.IPv4len)
+ }
+ copy(cm.Dst, pi.Addr[:])
+}
+
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
+ opt.Lock()
+ defer opt.Unlock()
+ if so, ok := sockOpts[ssoReceiveTTL]; ok && cf&FlagTTL != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagTTL)
+ } else {
+ opt.clear(FlagTTL)
+ }
+ }
+ if so, ok := sockOpts[ssoPacketInfo]; ok {
+ if cf&(FlagSrc|FlagDst|FlagInterface) != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(cf & (FlagSrc | FlagDst | FlagInterface))
+ } else {
+ opt.clear(cf & (FlagSrc | FlagDst | FlagInterface))
+ }
+ }
+ } else {
+ if so, ok := sockOpts[ssoReceiveDst]; ok && cf&FlagDst != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagDst)
+ } else {
+ opt.clear(FlagDst)
+ }
+ }
+ if so, ok := sockOpts[ssoReceiveInterface]; ok && cf&FlagInterface != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagInterface)
+ } else {
+ opt.clear(FlagInterface)
+ }
+ }
+ }
+ return nil
+}
diff --git a/ipv4/helper_posix_test.go b/ipv4/helper_posix_test.go
index ee66dd2..638eaf2 100644
--- a/ipv4/helper_posix_test.go
+++ b/ipv4/helper_posix_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package ipv4_test
diff --git a/ipv4/helper_stub_test.go b/ipv4/helper_stub_test.go
index 4ba0171..03ad2a9 100644
--- a/ipv4/helper_stub_test.go
+++ b/ipv4/helper_stub_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv4_test
diff --git a/ipv4/multicast_test.go b/ipv4/multicast_test.go
index 57e7a96..09463bf 100644
--- a/ipv4/multicast_test.go
+++ b/ipv4/multicast_test.go
@@ -30,7 +30,7 @@
func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
switch runtime.GOOS {
- case "fuchsia", "hurd", "illumos", "js", "nacl", "plan9", "solaris", "windows":
+ case "fuchsia", "hurd", "illumos", "js", "nacl", "plan9", "solaris", "windows", "zos":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
@@ -139,6 +139,11 @@
t.Skipf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
}
ifi, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
+ // Unable to obtain loopback interface on z/OS, so instead we test on any multicast
+ // capable interface.
+ if runtime.GOOS == "zos" {
+ ifi, err = nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast)
+ }
if err != nil {
t.Skip(err)
}
diff --git a/ipv4/multicastlistener_test.go b/ipv4/multicastlistener_test.go
index dc3f199..534ded6 100644
--- a/ipv4/multicastlistener_test.go
+++ b/ipv4/multicastlistener_test.go
@@ -21,7 +21,7 @@
func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) {
switch runtime.GOOS {
- case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+ case "fuchsia", "hurd", "js", "nacl", "plan9", "windows", "zos":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
@@ -61,7 +61,7 @@
func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
switch runtime.GOOS {
- case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+ case "fuchsia", "hurd", "js", "nacl", "plan9", "windows", "zos":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
@@ -116,7 +116,7 @@
func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
switch runtime.GOOS {
- case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+ case "fuchsia", "hurd", "js", "nacl", "plan9", "windows", "zos":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
@@ -172,7 +172,7 @@
func TestIPSingleRawConnWithSingleGroupListener(t *testing.T) {
switch runtime.GOOS {
- case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+ case "fuchsia", "hurd", "js", "nacl", "plan9", "windows", "zos":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
@@ -217,7 +217,7 @@
func TestIPPerInterfaceSingleRawConnWithSingleGroupListener(t *testing.T) {
switch runtime.GOOS {
- case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+ case "fuchsia", "hurd", "js", "nacl", "plan9", "windows", "zos":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
diff --git a/ipv4/multicastsockopt_test.go b/ipv4/multicastsockopt_test.go
index 234c775..b0ddd07 100644
--- a/ipv4/multicastsockopt_test.go
+++ b/ipv4/multicastsockopt_test.go
@@ -26,7 +26,7 @@
func TestPacketConnMulticastSocketOptions(t *testing.T) {
switch runtime.GOOS {
- case "fuchsia", "hurd", "js", "nacl", "plan9":
+ case "fuchsia", "hurd", "js", "nacl", "plan9", "zos":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
@@ -66,7 +66,7 @@
func TestRawConnMulticastSocketOptions(t *testing.T) {
switch runtime.GOOS {
- case "fuchsia", "hurd", "js", "nacl", "plan9":
+ case "fuchsia", "hurd", "js", "nacl", "plan9", "zos":
t.Skipf("not supported on %s", runtime.GOOS)
}
if !nettest.SupportsRawSocket() {
diff --git a/ipv4/payload_cmsg.go b/ipv4/payload_cmsg.go
index e761466..7bde689 100644
--- a/ipv4/payload_cmsg.go
+++ b/ipv4/payload_cmsg.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package ipv4
diff --git a/ipv4/payload_nocmsg.go b/ipv4/payload_nocmsg.go
index 1116256..251bd0c 100644
--- a/ipv4/payload_nocmsg.go
+++ b/ipv4/payload_nocmsg.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package ipv4
diff --git a/ipv4/sockopt_posix.go b/ipv4/sockopt_posix.go
index dea6451..ef29718 100644
--- a/ipv4/sockopt_posix.go
+++ b/ipv4/sockopt_posix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package ipv4
diff --git a/ipv4/sockopt_stub.go b/ipv4/sockopt_stub.go
index 37d4806..fbca526 100644
--- a/ipv4/sockopt_stub.go
+++ b/ipv4/sockopt_stub.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv4
diff --git a/ipv4/sys_stub.go b/ipv4/sys_stub.go
index b9c85b3..5555851 100644
--- a/ipv4/sys_stub.go
+++ b/ipv4/sys_stub.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv4
diff --git a/ipv4/sys_zos.go b/ipv4/sys_zos.go
new file mode 100644
index 0000000..7426606
--- /dev/null
+++ b/ipv4/sys_zos.go
@@ -0,0 +1,55 @@
+// Copyright 2020 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"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+)
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlPacketInfo: {sysIP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ 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}},
+ ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVPKTINFO, 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 (pi *inetPktinfo) setIfindex(i int) {
+ pi.Ifindex = uint32(i)
+}
+
+func (gr *groupReq) setGroup(grp net.IP) {
+ sa := (*sockaddrInet4)(unsafe.Pointer(&gr.Group))
+ sa.Family = syscall.AF_INET
+ sa.Len = sizeofSockaddrInet4
+ copy(sa.Addr[:], grp)
+}
+
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+ sa := (*sockaddrInet4)(unsafe.Pointer(&gsr.Group))
+ sa.Family = syscall.AF_INET
+ sa.Len = sizeofSockaddrInet4
+ copy(sa.Addr[:], grp)
+ sa = (*sockaddrInet4)(unsafe.Pointer(&gsr.Source))
+ sa.Family = syscall.AF_INET
+ sa.Len = sizeofSockaddrInet4
+ copy(sa.Addr[:], src)
+}
diff --git a/ipv4/unicast_test.go b/ipv4/unicast_test.go
index fce18b0..a2b0338 100644
--- a/ipv4/unicast_test.go
+++ b/ipv4/unicast_test.go
@@ -23,7 +23,9 @@
case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
- if _, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback); err != nil {
+ // Skip this check on z/OS since net.Interfaces() does not return loopback, however
+ // this does not affect the test and it will still pass.
+ if _, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback); err != nil && runtime.GOOS != "zos" {
t.Skipf("not available on %s", runtime.GOOS)
}
@@ -76,7 +78,9 @@
if !nettest.SupportsRawSocket() {
t.Skipf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
}
- if _, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback); err != nil {
+ // Skip this check on z/OS since net.Interfaces() does not return loopback, however
+ // this does not affect the test and it will still pass.
+ if _, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback); err != nil && runtime.GOOS != "zos" {
t.Skipf("not available on %s", runtime.GOOS)
}
diff --git a/ipv4/unicastsockopt_test.go b/ipv4/unicastsockopt_test.go
index 7527bc1..58d653e 100644
--- a/ipv4/unicastsockopt_test.go
+++ b/ipv4/unicastsockopt_test.go
@@ -16,7 +16,7 @@
func TestConnUnicastSocketOptions(t *testing.T) {
switch runtime.GOOS {
- case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+ case "fuchsia", "hurd", "js", "nacl", "plan9", "windows", "zos":
t.Skipf("not supported on %s", runtime.GOOS)
}
if _, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback); err != nil {
@@ -61,7 +61,7 @@
func TestPacketConnUnicastSocketOptions(t *testing.T) {
switch runtime.GOOS {
- case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+ case "fuchsia", "hurd", "js", "nacl", "plan9", "windows", "zos":
t.Skipf("not supported on %s", runtime.GOOS)
}
if _, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback); err != nil {
@@ -86,7 +86,7 @@
func TestRawConnUnicastSocketOptions(t *testing.T) {
switch runtime.GOOS {
- case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+ case "fuchsia", "hurd", "js", "nacl", "plan9", "windows", "zos":
t.Skipf("not supported on %s", runtime.GOOS)
}
if !nettest.SupportsRawSocket() {
diff --git a/ipv4/zsys_zos_s390x.go b/ipv4/zsys_zos_s390x.go
new file mode 100644
index 0000000..4bbfda0
--- /dev/null
+++ b/ipv4/zsys_zos_s390x.go
@@ -0,0 +1,80 @@
+// Copyright 2020 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.
+
+// Hand edited based on zerrors_zos_s390x.go
+// TODO(Bill O'Farrell): auto-generate.
+
+package ipv4
+
+const (
+ sysIP_ADD_MEMBERSHIP = 5
+ sysIP_ADD_SOURCE_MEMBERSHIP = 12
+ sysIP_BLOCK_SOURCE = 10
+ sysIP_DEFAULT_MULTICAST_LOOP = 1
+ sysIP_DEFAULT_MULTICAST_TTL = 1
+ sysIP_DROP_MEMBERSHIP = 6
+ sysIP_DROP_SOURCE_MEMBERSHIP = 13
+ sysIP_MAX_MEMBERSHIPS = 20
+ sysIP_MULTICAST_IF = 7
+ sysIP_MULTICAST_LOOP = 4
+ sysIP_MULTICAST_TTL = 3
+ sysIP_OPTIONS = 1
+ sysIP_PKTINFO = 101
+ sysIP_RECVPKTINFO = 102
+ sysIP_TOS = 2
+ sysIP_UNBLOCK_SOURCE = 11
+
+ sysMCAST_JOIN_GROUP = 40
+ sysMCAST_LEAVE_GROUP = 41
+ sysMCAST_JOIN_SOURCE_GROUP = 42
+ sysMCAST_LEAVE_SOURCE_GROUP = 43
+ sysMCAST_BLOCK_SOURCE = 44
+ sysMCAST_UNBLOCK_SOURCE = 45
+
+ sizeofIPMreq = 8
+ sizeofSockaddrInet4 = 16
+ sizeofSockaddrStorage = 128
+ sizeofGroupReq = 136
+ sizeofGroupSourceReq = 264
+ sizeofInetPktinfo = 8
+)
+
+type sockaddrInet4 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Addr [4]byte
+ Zero [8]uint8
+}
+
+type inetPktinfo struct {
+ Addr [4]byte
+ Ifindex uint32
+}
+
+type sockaddrStorage struct {
+ Len uint8
+ Family byte
+ ss_pad1 [6]byte
+ ss_align int64
+ ss_pad2 [112]byte
+}
+
+type groupReq struct {
+ Interface uint32
+ reserved uint32
+ Group sockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ reserved uint32
+ Group sockaddrStorage
+ Source sockaddrStorage
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
diff --git a/ipv6/control_rfc3542_unix.go b/ipv6/control_rfc3542_unix.go
index 8c221b5..77c449e 100644
--- a/ipv6/control_rfc3542_unix.go
+++ b/ipv6/control_rfc3542_unix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package ipv6
diff --git a/ipv6/control_stub.go b/ipv6/control_stub.go
index 1d773cb..e50b886 100644
--- a/ipv6/control_stub.go
+++ b/ipv6/control_stub.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv6
diff --git a/ipv6/control_unix.go b/ipv6/control_unix.go
index 0971a00..ec31ca2 100644
--- a/ipv6/control_unix.go
+++ b/ipv6/control_unix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package ipv6
diff --git a/ipv6/helper_posix_test.go b/ipv6/helper_posix_test.go
index cc85cea..6f5e78f 100644
--- a/ipv6/helper_posix_test.go
+++ b/ipv6/helper_posix_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package ipv6_test
diff --git a/ipv6/helper_stub_test.go b/ipv6/helper_stub_test.go
index cc515d1..066de62 100644
--- a/ipv6/helper_stub_test.go
+++ b/ipv6/helper_stub_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv6_test
diff --git a/ipv6/helper_unix_test.go b/ipv6/helper_unix_test.go
index d94d912..e76d1ca 100644
--- a/ipv6/helper_unix_test.go
+++ b/ipv6/helper_unix_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package ipv6_test
diff --git a/ipv6/icmp_stub.go b/ipv6/icmp_stub.go
index 370e51a..297e191 100644
--- a/ipv6/icmp_stub.go
+++ b/ipv6/icmp_stub.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv6
diff --git a/ipv6/icmp_zos.go b/ipv6/icmp_zos.go
new file mode 100644
index 0000000..ddf8f09
--- /dev/null
+++ b/ipv6/icmp_zos.go
@@ -0,0 +1,29 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+func (f *icmpv6Filter) accept(typ ICMPType) {
+ f.Filt[typ>>5] |= 1 << (uint32(typ) & 31)
+
+}
+
+func (f *icmpv6Filter) block(typ ICMPType) {
+ f.Filt[typ>>5] &^= 1 << (uint32(typ) & 31)
+
+}
+
+func (f *icmpv6Filter) setAll(block bool) {
+ for i := range f.Filt {
+ if block {
+ f.Filt[i] = 0
+ } else {
+ f.Filt[i] = 1<<32 - 1
+ }
+ }
+}
+
+func (f *icmpv6Filter) willBlock(typ ICMPType) bool {
+ return f.Filt[typ>>5]&(1<<(uint32(typ)&31)) == 0
+}
diff --git a/ipv6/multicastlistener_test.go b/ipv6/multicastlistener_test.go
index 66699ab..353327e 100644
--- a/ipv6/multicastlistener_test.go
+++ b/ipv6/multicastlistener_test.go
@@ -61,7 +61,7 @@
func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
switch runtime.GOOS {
- case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+ case "fuchsia", "hurd", "js", "nacl", "plan9", "windows", "zos":
t.Skipf("not supported on %s", runtime.GOOS)
}
if !nettest.SupportsIPv6() {
diff --git a/ipv6/payload_cmsg.go b/ipv6/payload_cmsg.go
index 284a042..8baa26e 100644
--- a/ipv6/payload_cmsg.go
+++ b/ipv6/payload_cmsg.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package ipv6
diff --git a/ipv6/payload_nocmsg.go b/ipv6/payload_nocmsg.go
index c5a4c96..00c4f58 100644
--- a/ipv6/payload_nocmsg.go
+++ b/ipv6/payload_nocmsg.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package ipv6
diff --git a/ipv6/sockopt_posix.go b/ipv6/sockopt_posix.go
index 824c623..f718792 100644
--- a/ipv6/sockopt_posix.go
+++ b/ipv6/sockopt_posix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package ipv6
diff --git a/ipv6/sockopt_stub.go b/ipv6/sockopt_stub.go
index 0a87a93..d87db6a 100644
--- a/ipv6/sockopt_stub.go
+++ b/ipv6/sockopt_stub.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv6
diff --git a/ipv6/sockopt_test.go b/ipv6/sockopt_test.go
index cbba049..8ac322b 100644
--- a/ipv6/sockopt_test.go
+++ b/ipv6/sockopt_test.go
@@ -17,7 +17,7 @@
func TestConnInitiatorPathMTU(t *testing.T) {
switch runtime.GOOS {
- case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+ case "fuchsia", "hurd", "js", "nacl", "plan9", "windows", "zos":
t.Skipf("not supported on %s", runtime.GOOS)
}
if !nettest.SupportsIPv6() {
@@ -55,7 +55,7 @@
func TestConnResponderPathMTU(t *testing.T) {
switch runtime.GOOS {
- case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+ case "fuchsia", "hurd", "js", "nacl", "plan9", "windows", "zos":
t.Skipf("not supported on %s", runtime.GOOS)
}
if !nettest.SupportsIPv6() {
diff --git a/ipv6/sys_ssmreq.go b/ipv6/sys_ssmreq.go
index 9b52e97..88d64f1 100644
--- a/ipv6/sys_ssmreq.go
+++ b/ipv6/sys_ssmreq.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin freebsd linux solaris
+// +build aix darwin freebsd linux solaris zos
package ipv6
diff --git a/ipv6/sys_ssmreq_stub.go b/ipv6/sys_ssmreq_stub.go
index d5bc110..b070886 100644
--- a/ipv6/sys_ssmreq_stub.go
+++ b/ipv6/sys_ssmreq_stub.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!freebsd,!linux,!solaris
+// +build !aix,!darwin,!freebsd,!linux,!solaris,!zos
package ipv6
diff --git a/ipv6/sys_stub.go b/ipv6/sys_stub.go
index 4f252d0..cbe4a02 100644
--- a/ipv6/sys_stub.go
+++ b/ipv6/sys_stub.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv6
diff --git a/ipv6/sys_zos.go b/ipv6/sys_zos.go
new file mode 100644
index 0000000..d4567f9
--- /dev/null
+++ b/ipv6/sys_zos.go
@@ -0,0 +1,70 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+ "net"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+)
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlHopLimit: {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
+ ctlPacketInfo: {sysIPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlPathMTU: {sysIPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_TCLASS, Len: 4}},
+ ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}},
+ ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVTCLASS, Len: 4}},
+ ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVHOPLIMIT, Len: 4}},
+ ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPKTINFO, Len: 4}},
+ ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPATHMTU, Len: 4}},
+ ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_CHECKSUM, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: sysICMP6_FILTER, Len: sizeofICMPv6Filter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ }
+)
+
+func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], ip)
+ sa.Scope_id = uint32(i)
+}
+
+func (pi *inet6Pktinfo) setIfindex(i int) {
+ pi.Ifindex = uint32(i)
+}
+
+func (gr *groupReq) setGroup(grp net.IP) {
+ sa := (*sockaddrInet6)(unsafe.Pointer(&gr.Group))
+ sa.Family = syscall.AF_INET6
+ sa.Len = sizeofSockaddrInet6
+ copy(sa.Addr[:], grp)
+}
+
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+ sa := (*sockaddrInet6)(unsafe.Pointer(&gsr.Group))
+ sa.Family = syscall.AF_INET6
+ sa.Len = sizeofSockaddrInet6
+ copy(sa.Addr[:], grp)
+ sa = (*sockaddrInet6)(unsafe.Pointer(&gsr.Source))
+ sa.Family = syscall.AF_INET6
+ sa.Len = sizeofSockaddrInet6
+ copy(sa.Addr[:], src)
+}
diff --git a/ipv6/unicast_test.go b/ipv6/unicast_test.go
index a7429f4..32c42c9 100644
--- a/ipv6/unicast_test.go
+++ b/ipv6/unicast_test.go
@@ -78,7 +78,7 @@
func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
switch runtime.GOOS {
- case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+ case "fuchsia", "hurd", "js", "nacl", "plan9", "windows", "zos":
t.Skipf("not supported on %s", runtime.GOOS)
}
if !nettest.SupportsIPv6() {
diff --git a/ipv6/zsys_zos_s390x.go b/ipv6/zsys_zos_s390x.go
new file mode 100644
index 0000000..3f98069
--- /dev/null
+++ b/ipv6/zsys_zos_s390x.go
@@ -0,0 +1,106 @@
+// Copyright 2020 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.
+
+// Hand edited based on zerrors_zos_s390x.go
+// TODO(Bill O'Farrell): auto-generate.
+
+package ipv6
+
+const (
+ sysIPV6_ADDR_PREFERENCES = 32
+ sysIPV6_CHECKSUM = 19
+ sysIPV6_DONTFRAG = 29
+ sysIPV6_DSTOPTS = 23
+ sysIPV6_HOPLIMIT = 11
+ sysIPV6_HOPOPTS = 22
+ sysIPV6_JOIN_GROUP = 5
+ sysIPV6_LEAVE_GROUP = 6
+ sysIPV6_MULTICAST_HOPS = 9
+ sysIPV6_MULTICAST_IF = 7
+ sysIPV6_MULTICAST_LOOP = 4
+ sysIPV6_NEXTHOP = 20
+ sysIPV6_PATHMTU = 12
+ sysIPV6_PKTINFO = 13
+ sysIPV6_PREFER_SRC_CGA = 0x10
+ sysIPV6_PREFER_SRC_COA = 0x02
+ sysIPV6_PREFER_SRC_HOME = 0x01
+ sysIPV6_PREFER_SRC_NONCGA = 0x20
+ sysIPV6_PREFER_SRC_PUBLIC = 0x08
+ sysIPV6_PREFER_SRC_TMP = 0x04
+ sysIPV6_RECVDSTOPTS = 28
+ sysIPV6_RECVHOPLIMIT = 14
+ sysIPV6_RECVHOPOPTS = 26
+ sysIPV6_RECVPATHMTU = 16
+ sysIPV6_RECVPKTINFO = 15
+ sysIPV6_RECVRTHDR = 25
+ sysIPV6_RECVTCLASS = 31
+ sysIPV6_RTHDR = 21
+ sysIPV6_RTHDRDSTOPTS = 24
+ sysIPV6_RTHDR_TYPE_0 = 0
+ sysIPV6_TCLASS = 30
+ sysIPV6_UNICAST_HOPS = 3
+ sysIPV6_USE_MIN_MTU = 18
+ sysIPV6_V6ONLY = 10
+
+ sysMCAST_JOIN_GROUP = 40
+ sysMCAST_LEAVE_GROUP = 41
+ sysMCAST_JOIN_SOURCE_GROUP = 42
+ sysMCAST_LEAVE_SOURCE_GROUP = 43
+ sysMCAST_BLOCK_SOURCE = 44
+ sysMCAST_UNBLOCK_SOURCE = 45
+
+ sysICMP6_FILTER = 0x1
+
+ sizeofSockaddrStorage = 128
+ sizeofICMPv6Filter = 32
+ sizeofInet6Pktinfo = 20
+ sizeofIPv6Mtuinfo = 32
+ sizeofSockaddrInet6 = 28
+ sizeofGroupReq = 136
+ sizeofGroupSourceReq = 264
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family byte
+ ss_pad1 [6]byte
+ ss_align int64
+ ss_pad2 [112]byte
+}
+
+type sockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte
+ Ifindex uint32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ reserved uint32
+ Group sockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ reserved uint32
+ Group sockaddrStorage
+ Source sockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Filt [8]uint32
+}
diff --git a/nettest/nettest.go b/nettest/nettest.go
index 953562f..83ba858 100644
--- a/nettest/nettest.go
+++ b/nettest/nettest.go
@@ -126,7 +126,7 @@
}
case "unixpacket":
switch runtime.GOOS {
- case "aix", "android", "fuchsia", "hurd", "darwin", "ios", "js", "nacl", "plan9", "windows":
+ case "aix", "android", "fuchsia", "hurd", "darwin", "ios", "js", "nacl", "plan9", "windows", "zos":
return false
case "netbsd":
// It passes on amd64 at least. 386 fails
diff --git a/nettest/nettest_stub.go b/nettest/nettest_stub.go
index 2bb8c05..22c2461 100644
--- a/nettest/nettest_stub.go
+++ b/nettest/nettest_stub.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package nettest
diff --git a/nettest/nettest_unix.go b/nettest/nettest_unix.go
index afff744..c1b1359 100644
--- a/nettest/nettest_unix.go
+++ b/nettest/nettest_unix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package nettest
diff --git a/webdav/file.go b/webdav/file.go
index 9f53778..3fcc053 100644
--- a/webdav/file.go
+++ b/webdav/file.go
@@ -12,6 +12,7 @@
"os"
"path"
"path/filepath"
+ "runtime"
"strings"
"sync"
"time"
@@ -272,8 +273,14 @@
var n *memFSNode
if dir == nil {
// We're opening the root.
- if flag&(os.O_WRONLY|os.O_RDWR) != 0 {
- return nil, os.ErrPermission
+ if runtime.GOOS == "zos" {
+ if flag&os.O_WRONLY != 0 {
+ return nil, os.ErrPermission
+ }
+ } else {
+ if flag&(os.O_WRONLY|os.O_RDWR) != 0 {
+ return nil, os.ErrPermission
+ }
}
n, frag = &fs.root, "/"