Commit a7769702 authored by Mikio Hara's avatar Mikio Hara

ipv6: add support for solaris

This change adds support for Solaris.

To read and write IPv6 ancillary data using ControlMessage, ipv6 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 IPV6_CHECKSUM option for ICMP transport.

Fixes golang/go#17324.

Change-Id: Ie014665d94ae6e4955c95d3eea88db90332e20bd
Reviewed-on: https://go-review.googlesource.com/30176
Run-TryBot: Mikio Hara <mikioh.mikioh@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent c8c327cf
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // 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 ipv6 package ipv6
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build nacl plan9 solaris // +build nacl plan9
package ipv6 package ipv6
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // 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 ipv6 package ipv6
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
package ipv6 package ipv6
/* /*
#include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/icmp6.h> #include <netinet/icmp6.h>
*/ */
...@@ -53,6 +55,13 @@ const ( ...@@ -53,6 +55,13 @@ const (
sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS
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
sysIPV6_PREFER_SRC_HOME = C.IPV6_PREFER_SRC_HOME sysIPV6_PREFER_SRC_HOME = C.IPV6_PREFER_SRC_HOME
sysIPV6_PREFER_SRC_COA = C.IPV6_PREFER_SRC_COA sysIPV6_PREFER_SRC_COA = C.IPV6_PREFER_SRC_COA
sysIPV6_PREFER_SRC_PUBLIC = C.IPV6_PREFER_SRC_PUBLIC sysIPV6_PREFER_SRC_PUBLIC = C.IPV6_PREFER_SRC_PUBLIC
...@@ -76,15 +85,20 @@ const ( ...@@ -76,15 +85,20 @@ const (
sysICMP6_FILTER = C.ICMP6_FILTER sysICMP6_FILTER = C.ICMP6_FILTER
sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 sysSizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
sysSizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
sysSizeofIPv6Mtuinfo = C.sizeof_struct_ip6_mtuinfo sysSizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo
sysSizeofIPv6Mtuinfo = C.sizeof_struct_ip6_mtuinfo
sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
sysSizeofGroupReq = C.sizeof_struct_group_req
sysSizeofGroupSourceReq = C.sizeof_struct_group_source_req
sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
) )
type sysSockaddrStorage C.struct_sockaddr_storage
type sysSockaddrInet6 C.struct_sockaddr_in6 type sysSockaddrInet6 C.struct_sockaddr_in6
type sysInet6Pktinfo C.struct_in6_pktinfo type sysInet6Pktinfo C.struct_in6_pktinfo
...@@ -93,4 +107,8 @@ type sysIPv6Mtuinfo C.struct_ip6_mtuinfo ...@@ -93,4 +107,8 @@ type sysIPv6Mtuinfo C.struct_ip6_mtuinfo
type sysIPv6Mreq C.struct_ipv6_mreq type sysIPv6Mreq C.struct_ipv6_mreq
type sysGroupReq C.struct_group_req
type sysGroupSourceReq C.struct_group_source_req
type sysICMPv6Filter C.struct_icmp6_filter type sysICMPv6Filter C.struct_icmp6_filter
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd windows // +build darwin dragonfly freebsd linux netbsd openbsd windows solaris
package ipv6 package ipv6
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build nacl plan9 solaris // +build nacl plan9
package ipv6 package ipv6
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // 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 ipv6 package ipv6
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build nacl plan9 solaris // +build nacl plan9
package ipv6 package ipv6
......
...@@ -7,18 +7,23 @@ ...@@ -7,18 +7,23 @@
package ipv6 package ipv6
func (f *sysICMPv6Filter) accept(typ ICMPType) { func (f *sysICMPv6Filter) accept(typ ICMPType) {
// TODO(mikio): implement this f.X__icmp6_filt[typ>>5] |= 1 << (uint32(typ) & 31)
} }
func (f *sysICMPv6Filter) block(typ ICMPType) { func (f *sysICMPv6Filter) block(typ ICMPType) {
// TODO(mikio): implement this f.X__icmp6_filt[typ>>5] &^= 1 << (uint32(typ) & 31)
} }
func (f *sysICMPv6Filter) setAll(block bool) { func (f *sysICMPv6Filter) setAll(block bool) {
// TODO(mikio): implement this for i := range f.X__icmp6_filt {
if block {
f.X__icmp6_filt[i] = 0
} else {
f.X__icmp6_filt[i] = 1<<32 - 1
}
}
} }
func (f *sysICMPv6Filter) willBlock(typ ICMPType) bool { func (f *sysICMPv6Filter) willBlock(typ ICMPType) bool {
// TODO(mikio): implement this return f.X__icmp6_filt[typ>>5]&(1<<(uint32(typ)&31)) == 0
return false
} }
...@@ -34,7 +34,7 @@ func TestICMPString(t *testing.T) { ...@@ -34,7 +34,7 @@ func TestICMPString(t *testing.T) {
func TestICMPFilter(t *testing.T) { func TestICMPFilter(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
...@@ -61,7 +61,7 @@ func TestICMPFilter(t *testing.T) { ...@@ -61,7 +61,7 @@ func TestICMPFilter(t *testing.T) {
func TestSetICMPFilter(t *testing.T) { func TestSetICMPFilter(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
if !supportsIPv6 { if !supportsIPv6 {
......
...@@ -32,7 +32,7 @@ func TestPacketConnReadWriteMulticastUDP(t *testing.T) { ...@@ -32,7 +32,7 @@ func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
case "freebsd": // due to a bug on loopback marking case "freebsd": // due to a bug on loopback marking
// See http://www.freebsd.org/cgi/query-pr.cgi?pr=180065. // See http://www.freebsd.org/cgi/query-pr.cgi?pr=180065.
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
if !supportsIPv6 { if !supportsIPv6 {
...@@ -132,7 +132,7 @@ func TestPacketConnReadWriteMulticastICMP(t *testing.T) { ...@@ -132,7 +132,7 @@ func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
case "freebsd": // due to a bug on loopback marking case "freebsd": // due to a bug on loopback marking
// See http://www.freebsd.org/cgi/query-pr.cgi?pr=180065. // See http://www.freebsd.org/cgi/query-pr.cgi?pr=180065.
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
if !supportsIPv6 { if !supportsIPv6 {
...@@ -205,7 +205,11 @@ func TestPacketConnReadWriteMulticastICMP(t *testing.T) { ...@@ -205,7 +205,11 @@ func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
if toggle { if toggle {
psh = nil psh = nil
if err := p.SetChecksum(true, 2); err != nil { if err := p.SetChecksum(true, 2); err != nil {
t.Fatal(err) // Solaris never allows to
// modify ICMP properties.
if runtime.GOOS != "solaris" {
t.Fatal(err)
}
} }
} else { } else {
psh = pshicmp psh = pshicmp
......
...@@ -22,7 +22,7 @@ var udpMultipleGroupListenerTests = []net.Addr{ ...@@ -22,7 +22,7 @@ var udpMultipleGroupListenerTests = []net.Addr{
func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) { func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
if !supportsIPv6 { if !supportsIPv6 {
...@@ -62,7 +62,7 @@ func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) { ...@@ -62,7 +62,7 @@ func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) {
func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) { func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
if !supportsIPv6 { if !supportsIPv6 {
...@@ -114,7 +114,7 @@ func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) { ...@@ -114,7 +114,7 @@ func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) { func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
if !supportsIPv6 { if !supportsIPv6 {
...@@ -157,7 +157,7 @@ func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) { ...@@ -157,7 +157,7 @@ func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
func TestIPSinglePacketConnWithSingleGroupListener(t *testing.T) { func TestIPSinglePacketConnWithSingleGroupListener(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
if !supportsIPv6 { if !supportsIPv6 {
...@@ -201,7 +201,7 @@ func TestIPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) { ...@@ -201,7 +201,7 @@ func TestIPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "darwin", "dragonfly", "openbsd": // platforms that return fe80::1%lo0: bind: can't assign requested address case "darwin", "dragonfly", "openbsd": // platforms that return fe80::1%lo0: bind: can't assign requested address
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
if !supportsIPv6 { if !supportsIPv6 {
......
...@@ -26,7 +26,7 @@ var packetConnMulticastSocketOptionTests = []struct { ...@@ -26,7 +26,7 @@ var packetConnMulticastSocketOptionTests = []struct {
func TestPacketConnMulticastSocketOptions(t *testing.T) { func TestPacketConnMulticastSocketOptions(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
if !supportsIPv6 { if !supportsIPv6 {
......
...@@ -102,7 +102,7 @@ func benchmarkReadWriteIPv6UDP(b *testing.B, p *ipv6.PacketConn, wb, rb []byte, ...@@ -102,7 +102,7 @@ func benchmarkReadWriteIPv6UDP(b *testing.B, p *ipv6.PacketConn, wb, rb []byte,
func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) { func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
if !supportsIPv6 { if !supportsIPv6 {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // 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 ipv6 package ipv6
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // 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 ipv6 package ipv6
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !darwin,!freebsd,!linux // +build !darwin,!freebsd,!linux,!solaris
package ipv6 package ipv6
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin freebsd linux // +build darwin freebsd linux solaris
package ipv6 package ipv6
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build nacl plan9 solaris // +build nacl plan9
package ipv6 package ipv6
......
...@@ -19,7 +19,7 @@ var supportsIPv6 bool = nettest.SupportsIPv6() ...@@ -19,7 +19,7 @@ var supportsIPv6 bool = nettest.SupportsIPv6()
func TestConnInitiatorPathMTU(t *testing.T) { func TestConnInitiatorPathMTU(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
if !supportsIPv6 { if !supportsIPv6 {
...@@ -57,7 +57,7 @@ func TestConnInitiatorPathMTU(t *testing.T) { ...@@ -57,7 +57,7 @@ func TestConnInitiatorPathMTU(t *testing.T) {
func TestConnResponderPathMTU(t *testing.T) { func TestConnResponderPathMTU(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
if !supportsIPv6 { if !supportsIPv6 {
...@@ -95,7 +95,7 @@ func TestConnResponderPathMTU(t *testing.T) { ...@@ -95,7 +95,7 @@ func TestConnResponderPathMTU(t *testing.T) {
func TestPacketConnChecksum(t *testing.T) { func TestPacketConnChecksum(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
if !supportsIPv6 { if !supportsIPv6 {
......
// 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 ipv6
import (
"net"
"syscall"
"unsafe"
"golang.org/x/net/internal/iana"
)
var (
ctlOpts = [ctlMax]ctlOpt{
ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
ctlHopLimit: {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
ctlPacketInfo: {sysIPV6_PKTINFO, sysSizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
ctlNextHop: {sysIPV6_NEXTHOP, sysSizeofSockaddrInet6, marshalNextHop, parseNextHop},
ctlPathMTU: {sysIPV6_PATHMTU, sysSizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
}
sockOpts = [ssoMax]sockOpt{
ssoTrafficClass: {iana.ProtocolIPv6, sysIPV6_TCLASS, ssoTypeInt},
ssoHopLimit: {iana.ProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt},
ssoMulticastInterface: {iana.ProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface},
ssoMulticastHopLimit: {iana.ProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt},
ssoMulticastLoopback: {iana.ProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt},
ssoReceiveTrafficClass: {iana.ProtocolIPv6, sysIPV6_RECVTCLASS, ssoTypeInt},
ssoReceiveHopLimit: {iana.ProtocolIPv6, sysIPV6_RECVHOPLIMIT, ssoTypeInt},
ssoReceivePacketInfo: {iana.ProtocolIPv6, sysIPV6_RECVPKTINFO, ssoTypeInt},
ssoReceivePathMTU: {iana.ProtocolIPv6, sysIPV6_RECVPATHMTU, ssoTypeInt},
ssoPathMTU: {iana.ProtocolIPv6, sysIPV6_PATHMTU, ssoTypeMTUInfo},
ssoChecksum: {iana.ProtocolIPv6, sysIPV6_CHECKSUM, ssoTypeInt},
ssoICMPFilter: {iana.ProtocolIPv6ICMP, sysICMP6_FILTER, ssoTypeICMPFilter},
ssoJoinGroup: {iana.ProtocolIPv6, sysMCAST_JOIN_GROUP, ssoTypeGroupReq},
ssoLeaveGroup: {iana.ProtocolIPv6, sysMCAST_LEAVE_GROUP, ssoTypeGroupReq},
ssoJoinSourceGroup: {iana.ProtocolIPv6, sysMCAST_JOIN_SOURCE_GROUP, ssoTypeGroupSourceReq},
ssoLeaveSourceGroup: {iana.ProtocolIPv6, sysMCAST_LEAVE_SOURCE_GROUP, ssoTypeGroupSourceReq},
ssoBlockSourceGroup: {iana.ProtocolIPv6, sysMCAST_BLOCK_SOURCE, ssoTypeGroupSourceReq},
ssoUnblockSourceGroup: {iana.ProtocolIPv6, sysMCAST_UNBLOCK_SOURCE, ssoTypeGroupSourceReq},
}
)
func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) {
sa.Family = syscall.AF_INET6
copy(sa.Addr[:], ip)
sa.Scope_id = uint32(i)
}
func (pi *sysInet6Pktinfo) setIfindex(i int) {
pi.Ifindex = uint32(i)
}
func (mreq *sysIPv6Mreq) setIfindex(i int) {
mreq.Interface = uint32(i)
}
func (gr *sysGroupReq) setGroup(grp net.IP) {
sa := (*sysSockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4))
sa.Family = syscall.AF_INET6
copy(sa.Addr[:], grp)
}
func (gsr *sysGroupSourceReq) setSourceGroup(grp, src net.IP) {
sa := (*sysSockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4))
sa.Family = syscall.AF_INET6
copy(sa.Addr[:], grp)
sa = (*sysSockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 260))
sa.Family = syscall.AF_INET6
copy(sa.Addr[:], src)
}
// 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)
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build nacl plan9 solaris // +build nacl plan9
package ipv6 package ipv6
......
// 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 ipv6
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
}
...@@ -20,7 +20,7 @@ import ( ...@@ -20,7 +20,7 @@ import (
func TestPacketConnReadWriteUnicastUDP(t *testing.T) { func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
if !supportsIPv6 { if !supportsIPv6 {
...@@ -81,7 +81,7 @@ func TestPacketConnReadWriteUnicastUDP(t *testing.T) { ...@@ -81,7 +81,7 @@ func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
func TestPacketConnReadWriteUnicastICMP(t *testing.T) { func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
if !supportsIPv6 { if !supportsIPv6 {
...@@ -127,7 +127,11 @@ func TestPacketConnReadWriteUnicastICMP(t *testing.T) { ...@@ -127,7 +127,11 @@ func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
if toggle { if toggle {
psh = nil psh = nil
if err := p.SetChecksum(true, 2); err != nil { if err := p.SetChecksum(true, 2); err != nil {
t.Fatal(err) // Solaris never allows to modify
// ICMP properties.
if runtime.GOOS != "solaris" {
t.Fatal(err)
}
} }
} else { } else {
psh = pshicmp psh = pshicmp
......
...@@ -16,7 +16,7 @@ import ( ...@@ -16,7 +16,7 @@ import (
func TestConnUnicastSocketOptions(t *testing.T) { func TestConnUnicastSocketOptions(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
if !supportsIPv6 { if !supportsIPv6 {
...@@ -52,7 +52,7 @@ var packetConnUnicastSocketOptionTests = []struct { ...@@ -52,7 +52,7 @@ var packetConnUnicastSocketOptionTests = []struct {
func TestPacketConnUnicastSocketOptions(t *testing.T) { func TestPacketConnUnicastSocketOptions(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows": case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS) t.Skipf("not supported on %s", runtime.GOOS)
} }
if !supportsIPv6 { if !supportsIPv6 {
......
...@@ -44,6 +44,13 @@ const ( ...@@ -44,6 +44,13 @@ const (
sysIPV6_RECVDSTOPTS = 0x28 sysIPV6_RECVDSTOPTS = 0x28
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
sysIPV6_PREFER_SRC_HOME = 0x1 sysIPV6_PREFER_SRC_HOME = 0x1
sysIPV6_PREFER_SRC_COA = 0x2 sysIPV6_PREFER_SRC_COA = 0x2
sysIPV6_PREFER_SRC_PUBLIC = 0x4 sysIPV6_PREFER_SRC_PUBLIC = 0x4
...@@ -67,15 +74,25 @@ const ( ...@@ -67,15 +74,25 @@ const (
sysICMP6_FILTER = 0x1 sysICMP6_FILTER = 0x1
sysSizeofSockaddrInet6 = 0x20 sysSizeofSockaddrStorage = 0x100
sysSizeofInet6Pktinfo = 0x14 sysSizeofSockaddrInet6 = 0x20
sysSizeofIPv6Mtuinfo = 0x24 sysSizeofInet6Pktinfo = 0x14
sysSizeofIPv6Mtuinfo = 0x24
sysSizeofIPv6Mreq = 0x14 sysSizeofIPv6Mreq = 0x14
sysSizeofGroupReq = 0x104
sysSizeofGroupSourceReq = 0x204
sysSizeofICMPv6Filter = 0x20 sysSizeofICMPv6Filter = 0x20
) )
type sysSockaddrStorage struct {
Family uint16
X_ss_pad1 [6]int8
X_ss_align float64
X_ss_pad2 [240]int8
}
type sysSockaddrInet6 struct { type sysSockaddrInet6 struct {
Family uint16 Family uint16
Port uint16 Port uint16
...@@ -100,6 +117,17 @@ type sysIPv6Mreq struct { ...@@ -100,6 +117,17 @@ type sysIPv6Mreq struct {
Interface uint32 Interface uint32
} }
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
}
type sysICMPv6Filter struct { type sysICMPv6Filter struct {
X__icmp6_filt [8]uint32 X__icmp6_filt [8]uint32
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment