ipv4: add support for solaris
This change adds support for Solaris.
To read and write IPv4 ancillary data using ControlMessage, ipv4 pacakge
requires https://go-review.googlesource.com/30171/
Note: Unlike other platforms, Solaris seems to have a few restrictions
on ICMP property access via raw IP sockets. At least applications are
prohibited from using IP_RECVTTL option for ICMP transport.
Fixes golang/go#17323.
Change-Id: Icb6dfa3c8eced28d14693ddfea4601301999d735
Reviewed-on: https://go-review.googlesource.com/30175
Run-TryBot: Mikio Hara <mikioh.mikioh@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/ipv4/control_pktinfo.go b/ipv4/control_pktinfo.go
index 444782f..90ccee1 100644
--- a/ipv4/control_pktinfo.go
+++ b/ipv4/control_pktinfo.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 darwin linux
+// +build darwin linux solaris
package ipv4
diff --git a/ipv4/control_stub.go b/ipv4/control_stub.go
index 5f5a1bd..88602c3 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 nacl plan9 solaris
+// +build nacl plan9
package ipv4
diff --git a/ipv4/control_unix.go b/ipv4/control_unix.go
index 6b6682d..668bb69 100644
--- a/ipv4/control_unix.go
+++ b/ipv4/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 darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package ipv4
diff --git a/ipv4/defs_solaris.go b/ipv4/defs_solaris.go
index bb74afa..c0b2d3b 100644
--- a/ipv4/defs_solaris.go
+++ b/ipv4/defs_solaris.go
@@ -9,30 +9,24 @@
package ipv4
/*
+#include <sys/socket.h>
+
#include <netinet/in.h>
*/
import "C"
const (
- sysIP_OPTIONS = C.IP_OPTIONS
- sysIP_HDRINCL = C.IP_HDRINCL
- sysIP_TOS = C.IP_TOS
- sysIP_TTL = C.IP_TTL
- sysIP_RECVOPTS = C.IP_RECVOPTS
- sysIP_RECVRETOPTS = C.IP_RECVRETOPTS
- sysIP_RECVDSTADDR = C.IP_RECVDSTADDR
- sysIP_RETOPTS = C.IP_RETOPTS
- sysIP_RECVIF = C.IP_RECVIF
- sysIP_RECVSLLA = C.IP_RECVSLLA
- sysIP_RECVTTL = C.IP_RECVTTL
- sysIP_NEXTHOP = C.IP_NEXTHOP
- sysIP_PKTINFO = C.IP_PKTINFO
- sysIP_RECVPKTINFO = C.IP_RECVPKTINFO
- sysIP_DONTFRAG = C.IP_DONTFRAG
- sysIP_BOUND_IF = C.IP_BOUND_IF
- sysIP_UNSPEC_SRC = C.IP_UNSPEC_SRC
- sysIP_BROADCAST_TTL = C.IP_BROADCAST_TTL
- sysIP_DHCPINIT_IF = C.IP_DHCPINIT_IF
+ sysIP_OPTIONS = C.IP_OPTIONS
+ sysIP_HDRINCL = C.IP_HDRINCL
+ sysIP_TOS = C.IP_TOS
+ sysIP_TTL = C.IP_TTL
+ sysIP_RECVOPTS = C.IP_RECVOPTS
+ sysIP_RECVRETOPTS = C.IP_RECVRETOPTS
+ sysIP_RECVDSTADDR = C.IP_RECVDSTADDR
+ sysIP_RETOPTS = C.IP_RETOPTS
+ sysIP_RECVIF = C.IP_RECVIF
+ sysIP_RECVSLLA = C.IP_RECVSLLA
+ sysIP_RECVTTL = C.IP_RECVTTL
sysIP_MULTICAST_IF = C.IP_MULTICAST_IF
sysIP_MULTICAST_TTL = C.IP_MULTICAST_TTL
@@ -43,15 +37,48 @@
sysIP_UNBLOCK_SOURCE = C.IP_UNBLOCK_SOURCE
sysIP_ADD_SOURCE_MEMBERSHIP = C.IP_ADD_SOURCE_MEMBERSHIP
sysIP_DROP_SOURCE_MEMBERSHIP = C.IP_DROP_SOURCE_MEMBERSHIP
+ sysIP_NEXTHOP = C.IP_NEXTHOP
- sysSizeofInetPktinfo = C.sizeof_struct_in_pktinfo
+ sysIP_PKTINFO = C.IP_PKTINFO
+ sysIP_RECVPKTINFO = C.IP_RECVPKTINFO
+ sysIP_DONTFRAG = C.IP_DONTFRAG
- sysSizeofIPMreq = C.sizeof_struct_ip_mreq
- sysSizeofIPMreqSource = C.sizeof_struct_ip_mreq_source
+ sysIP_BOUND_IF = C.IP_BOUND_IF
+ sysIP_UNSPEC_SRC = C.IP_UNSPEC_SRC
+ sysIP_BROADCAST_TTL = C.IP_BROADCAST_TTL
+ sysIP_DHCPINIT_IF = C.IP_DHCPINIT_IF
+
+ sysIP_REUSEADDR = C.IP_REUSEADDR
+ sysIP_DONTROUTE = C.IP_DONTROUTE
+ sysIP_BROADCAST = C.IP_BROADCAST
+
+ sysMCAST_JOIN_GROUP = C.MCAST_JOIN_GROUP
+ sysMCAST_LEAVE_GROUP = C.MCAST_LEAVE_GROUP
+ sysMCAST_BLOCK_SOURCE = C.MCAST_BLOCK_SOURCE
+ sysMCAST_UNBLOCK_SOURCE = C.MCAST_UNBLOCK_SOURCE
+ sysMCAST_JOIN_SOURCE_GROUP = C.MCAST_JOIN_SOURCE_GROUP
+ sysMCAST_LEAVE_SOURCE_GROUP = C.MCAST_LEAVE_SOURCE_GROUP
+
+ sysSizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
+ sysSizeofSockaddrInet = C.sizeof_struct_sockaddr_in
+ sysSizeofInetPktinfo = C.sizeof_struct_in_pktinfo
+
+ sysSizeofIPMreq = C.sizeof_struct_ip_mreq
+ sysSizeofIPMreqSource = C.sizeof_struct_ip_mreq_source
+ sysSizeofGroupReq = C.sizeof_struct_group_req
+ sysSizeofGroupSourceReq = C.sizeof_struct_group_source_req
)
+type sysSockaddrStorage C.struct_sockaddr_storage
+
+type sysSockaddrInet C.struct_sockaddr_in
+
type sysInetPktinfo C.struct_in_pktinfo
type sysIPMreq C.struct_ip_mreq
type sysIPMreqSource C.struct_ip_mreq_source
+
+type sysGroupReq C.struct_group_req
+
+type sysGroupSourceReq C.struct_group_source_req
diff --git a/ipv4/dgramopt_posix.go b/ipv4/dgramopt_posix.go
index 40b5e1c..693c137 100644
--- a/ipv4/dgramopt_posix.go
+++ b/ipv4/dgramopt_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 darwin dragonfly freebsd linux netbsd openbsd windows
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
package ipv4
diff --git a/ipv4/dgramopt_stub.go b/ipv4/dgramopt_stub.go
index b74df69..53cf1c6 100644
--- a/ipv4/dgramopt_stub.go
+++ b/ipv4/dgramopt_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 nacl plan9 solaris
+// +build nacl plan9
package ipv4
diff --git a/ipv4/genericopt_posix.go b/ipv4/genericopt_posix.go
index 53bc79f..f333581 100644
--- a/ipv4/genericopt_posix.go
+++ b/ipv4/genericopt_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 darwin dragonfly freebsd linux netbsd openbsd windows
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
package ipv4
diff --git a/ipv4/genericopt_stub.go b/ipv4/genericopt_stub.go
index 1817bad..f907189 100644
--- a/ipv4/genericopt_stub.go
+++ b/ipv4/genericopt_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 nacl plan9 solaris
+// +build nacl plan9
package ipv4
diff --git a/ipv4/multicast_test.go b/ipv4/multicast_test.go
index d2bcf85..5a0793c 100644
--- a/ipv4/multicast_test.go
+++ b/ipv4/multicast_test.go
@@ -166,7 +166,11 @@
if _, err := p.MulticastLoopback(); err != nil {
t.Fatal(err)
}
- cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
+ cf := ipv4.FlagDst | ipv4.FlagInterface
+ if runtime.GOOS != "solaris" {
+ // Solaris never allows to modify ICMP properties.
+ cf |= ipv4.FlagTTL
+ }
for i, toggle := range []bool{true, false, true} {
wb, err := (&icmp.Message{
diff --git a/ipv4/multicastlistener_test.go b/ipv4/multicastlistener_test.go
index e342bf1..ccac56a 100644
--- a/ipv4/multicastlistener_test.go
+++ b/ipv4/multicastlistener_test.go
@@ -21,7 +21,7 @@
func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) {
switch runtime.GOOS {
- case "nacl", "plan9", "solaris", "windows":
+ case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
@@ -61,7 +61,7 @@
func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
switch runtime.GOOS {
- case "nacl", "plan9", "solaris", "windows":
+ case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
@@ -113,7 +113,7 @@
func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
switch runtime.GOOS {
- case "nacl", "plan9", "solaris", "windows":
+ case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
@@ -156,7 +156,7 @@
func TestIPSingleRawConnWithSingleGroupListener(t *testing.T) {
switch runtime.GOOS {
- case "nacl", "plan9", "solaris", "windows":
+ case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
@@ -201,7 +201,7 @@
func TestIPPerInterfaceSingleRawConnWithSingleGroupListener(t *testing.T) {
switch runtime.GOOS {
- case "nacl", "plan9", "solaris", "windows":
+ case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
diff --git a/ipv4/multicastsockopt_test.go b/ipv4/multicastsockopt_test.go
index c76dbe4..d730d31 100644
--- a/ipv4/multicastsockopt_test.go
+++ b/ipv4/multicastsockopt_test.go
@@ -26,7 +26,7 @@
func TestPacketConnMulticastSocketOptions(t *testing.T) {
switch runtime.GOOS {
- case "nacl", "plan9", "solaris":
+ case "nacl", "plan9":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
@@ -66,7 +66,7 @@
func TestRawConnMulticastSocketOptions(t *testing.T) {
switch runtime.GOOS {
- case "nacl", "plan9", "solaris":
+ case "nacl", "plan9":
t.Skipf("not supported on %s", runtime.GOOS)
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
diff --git a/ipv4/payload_cmsg.go b/ipv4/payload_cmsg.go
index d358fc3..5da0cbe 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 !plan9,!solaris,!windows
+// +build !plan9,!windows
package ipv4
diff --git a/ipv4/payload_nocmsg.go b/ipv4/payload_nocmsg.go
index d128c9c..b874de0 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 plan9 solaris windows
+// +build plan9 windows
package ipv4
diff --git a/ipv4/readwrite_test.go b/ipv4/readwrite_test.go
index 247d06c..a3d71d1 100644
--- a/ipv4/readwrite_test.go
+++ b/ipv4/readwrite_test.go
@@ -91,7 +91,7 @@
func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) {
switch runtime.GOOS {
- case "nacl", "plan9", "solaris", "windows":
+ case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
diff --git a/ipv4/sockopt_asmreq.go b/ipv4/sockopt_asmreq.go
index 4a6aa78..cc55201 100644
--- a/ipv4/sockopt_asmreq.go
+++ b/ipv4/sockopt_asmreq.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 darwin dragonfly freebsd netbsd openbsd windows
+// +build darwin dragonfly freebsd netbsd openbsd solaris windows
package ipv4
diff --git a/ipv4/sockopt_asmreq_posix.go b/ipv4/sockopt_asmreq_posix.go
index ef9b139..9207dea 100644
--- a/ipv4/sockopt_asmreq_posix.go
+++ b/ipv4/sockopt_asmreq_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 darwin dragonfly freebsd netbsd openbsd windows
+// +build darwin dragonfly freebsd netbsd openbsd solaris windows
package ipv4
diff --git a/ipv4/sockopt_asmreq_stub.go b/ipv4/sockopt_asmreq_stub.go
index 9f7b655..0fbdf47 100644
--- a/ipv4/sockopt_asmreq_stub.go
+++ b/ipv4/sockopt_asmreq_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 !darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!windows
+// +build !darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!windows
package ipv4
diff --git a/ipv4/sockopt_posix.go b/ipv4/sockopt_posix.go
index 0b7d6b6..da68143 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 darwin dragonfly freebsd linux netbsd openbsd windows
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
package ipv4
diff --git a/ipv4/sockopt_ssmreq_stub.go b/ipv4/sockopt_ssmreq_stub.go
index e2d98fd..0287396 100644
--- a/ipv4/sockopt_ssmreq_stub.go
+++ b/ipv4/sockopt_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 !darwin,!freebsd,!linux
+// +build !darwin,!freebsd,!linux,!solaris
package ipv4
diff --git a/ipv4/sockopt_ssmreq_unix.go b/ipv4/sockopt_ssmreq_unix.go
index 588e9b9..adccd45 100644
--- a/ipv4/sockopt_ssmreq_unix.go
+++ b/ipv4/sockopt_ssmreq_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 darwin freebsd linux
+// +build darwin freebsd linux solaris
package ipv4
diff --git a/ipv4/sockopt_stub.go b/ipv4/sockopt_stub.go
index 7cfe57c..c7278c1 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 nacl plan9 solaris
+// +build nacl plan9
package ipv4
diff --git a/ipv4/sys_solaris.go b/ipv4/sys_solaris.go
new file mode 100644
index 0000000..fd7532b
--- /dev/null
+++ b/ipv4/sys_solaris.go
@@ -0,0 +1,54 @@
+// 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 (
+ "net"
+ "syscall"
+ "unsafe"
+)
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlTTL: {sysIP_RECVTTL, 4, marshalTTL, parseTTL},
+ ctlPacketInfo: {sysIP_PKTINFO, sysSizeofInetPktinfo, 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},
+ }
+)
+
+func (pi *sysInetPktinfo) setIfindex(i int) {
+ pi.Ifindex = uint32(i)
+}
+
+func (gr *sysGroupReq) setGroup(grp net.IP) {
+ sa := (*sysSockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4))
+ sa.Family = syscall.AF_INET
+ copy(sa.Addr[:], grp)
+}
+
+func (gsr *sysGroupSourceReq) setSourceGroup(grp, src net.IP) {
+ sa := (*sysSockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4))
+ sa.Family = syscall.AF_INET
+ copy(sa.Addr[:], grp)
+ sa = (*sysSockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 260))
+ sa.Family = syscall.AF_INET
+ copy(sa.Addr[:], src)
+}
diff --git a/ipv4/sys_solaris_amd64.s b/ipv4/sys_solaris_amd64.s
new file mode 100644
index 0000000..39d76af
--- /dev/null
+++ b/ipv4/sys_solaris_amd64.s
@@ -0,0 +1,8 @@
+// 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_stub.go b/ipv4/sys_stub.go
index c8e55cb..d6dd812 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 nacl plan9 solaris
+// +build nacl plan9
package ipv4
diff --git a/ipv4/syscall_solaris.go b/ipv4/syscall_solaris.go
new file mode 100644
index 0000000..3b11288
--- /dev/null
+++ b/ipv4/syscall_solaris.go
@@ -0,0 +1,40 @@
+// 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 solaris
+
+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/unicast_test.go b/ipv4/unicast_test.go
index 9c632cd..8d57fd0 100644
--- a/ipv4/unicast_test.go
+++ b/ipv4/unicast_test.go
@@ -20,7 +20,7 @@
func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
switch runtime.GOOS {
- case "nacl", "plan9", "solaris", "windows":
+ case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
@@ -74,7 +74,7 @@
func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
switch runtime.GOOS {
- case "nacl", "plan9", "solaris", "windows":
+ case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
@@ -97,7 +97,11 @@
}
p := ipv4.NewPacketConn(c)
defer p.Close()
- cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
+ cf := ipv4.FlagDst | ipv4.FlagInterface
+ if runtime.GOOS != "solaris" {
+ // Solaris never allows to modify ICMP properties.
+ cf |= ipv4.FlagTTL
+ }
for i, toggle := range []bool{true, false, true} {
wb, err := (&icmp.Message{
@@ -156,7 +160,7 @@
func TestRawConnReadWriteUnicastICMP(t *testing.T) {
switch runtime.GOOS {
- case "nacl", "plan9", "solaris", "windows":
+ case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
diff --git a/ipv4/unicastsockopt_test.go b/ipv4/unicastsockopt_test.go
index 25606f2..258247b 100644
--- a/ipv4/unicastsockopt_test.go
+++ b/ipv4/unicastsockopt_test.go
@@ -16,7 +16,7 @@
func TestConnUnicastSocketOptions(t *testing.T) {
switch runtime.GOOS {
- case "nacl", "plan9", "solaris":
+ case "nacl", "plan9":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
@@ -53,7 +53,7 @@
func TestPacketConnUnicastSocketOptions(t *testing.T) {
switch runtime.GOOS {
- case "nacl", "plan9", "solaris":
+ case "nacl", "plan9":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
@@ -79,7 +79,7 @@
func TestRawConnUnicastSocketOptions(t *testing.T) {
switch runtime.GOOS {
- case "nacl", "plan9", "solaris":
+ case "nacl", "plan9":
t.Skipf("not supported on %s", runtime.GOOS)
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
diff --git a/ipv4/zsys_solaris.go b/ipv4/zsys_solaris.go
index d7c2334..a817a19 100644
--- a/ipv4/zsys_solaris.go
+++ b/ipv4/zsys_solaris.go
@@ -6,25 +6,17 @@
package ipv4
const (
- sysIP_OPTIONS = 0x1
- sysIP_HDRINCL = 0x2
- sysIP_TOS = 0x3
- sysIP_TTL = 0x4
- sysIP_RECVOPTS = 0x5
- sysIP_RECVRETOPTS = 0x6
- sysIP_RECVDSTADDR = 0x7
- sysIP_RETOPTS = 0x8
- sysIP_RECVIF = 0x9
- sysIP_RECVSLLA = 0xa
- sysIP_RECVTTL = 0xb
- sysIP_NEXTHOP = 0x19
- sysIP_PKTINFO = 0x1a
- sysIP_RECVPKTINFO = 0x1a
- sysIP_DONTFRAG = 0x1b
- sysIP_BOUND_IF = 0x41
- sysIP_UNSPEC_SRC = 0x42
- sysIP_BROADCAST_TTL = 0x43
- sysIP_DHCPINIT_IF = 0x45
+ sysIP_OPTIONS = 0x1
+ sysIP_HDRINCL = 0x2
+ sysIP_TOS = 0x3
+ sysIP_TTL = 0x4
+ sysIP_RECVOPTS = 0x5
+ sysIP_RECVRETOPTS = 0x6
+ sysIP_RECVDSTADDR = 0x7
+ sysIP_RETOPTS = 0x8
+ sysIP_RECVIF = 0x9
+ sysIP_RECVSLLA = 0xa
+ sysIP_RECVTTL = 0xb
sysIP_MULTICAST_IF = 0x10
sysIP_MULTICAST_TTL = 0x11
@@ -35,13 +27,52 @@
sysIP_UNBLOCK_SOURCE = 0x16
sysIP_ADD_SOURCE_MEMBERSHIP = 0x17
sysIP_DROP_SOURCE_MEMBERSHIP = 0x18
+ sysIP_NEXTHOP = 0x19
- sysSizeofInetPktinfo = 0xc
+ sysIP_PKTINFO = 0x1a
+ sysIP_RECVPKTINFO = 0x1a
+ sysIP_DONTFRAG = 0x1b
- sysSizeofIPMreq = 0x8
- sysSizeofIPMreqSource = 0xc
+ sysIP_BOUND_IF = 0x41
+ sysIP_UNSPEC_SRC = 0x42
+ sysIP_BROADCAST_TTL = 0x43
+ sysIP_DHCPINIT_IF = 0x45
+
+ sysIP_REUSEADDR = 0x104
+ sysIP_DONTROUTE = 0x105
+ sysIP_BROADCAST = 0x106
+
+ sysMCAST_JOIN_GROUP = 0x29
+ sysMCAST_LEAVE_GROUP = 0x2a
+ sysMCAST_BLOCK_SOURCE = 0x2b
+ sysMCAST_UNBLOCK_SOURCE = 0x2c
+ sysMCAST_JOIN_SOURCE_GROUP = 0x2d
+ sysMCAST_LEAVE_SOURCE_GROUP = 0x2e
+
+ sysSizeofSockaddrStorage = 0x100
+ sysSizeofSockaddrInet = 0x10
+ sysSizeofInetPktinfo = 0xc
+
+ sysSizeofIPMreq = 0x8
+ sysSizeofIPMreqSource = 0xc
+ sysSizeofGroupReq = 0x104
+ sysSizeofGroupSourceReq = 0x204
)
+type sysSockaddrStorage struct {
+ Family uint16
+ X_ss_pad1 [6]int8
+ X_ss_align float64
+ X_ss_pad2 [240]int8
+}
+
+type sysSockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ Zero [8]int8
+}
+
type sysInetPktinfo struct {
Ifindex uint32
Spec_dst [4]byte /* in_addr */
@@ -58,3 +89,14 @@
Sourceaddr [4]byte /* in_addr */
Interface [4]byte /* in_addr */
}
+
+type sysGroupReq struct {
+ Interface uint32
+ Pad_cgo_0 [256]byte
+}
+
+type sysGroupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [256]byte
+ Pad_cgo_1 [256]byte
+}