diff --git a/ipv6/sys.go b/ipv6/sys.go deleted file mode 100644 index 18b1acac..00000000 --- a/ipv6/sys.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2013 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 - -type sysSockoptLen uint32 - -const ( - sysSizeofPacketInfo = 0x14 - sysSizeofMulticastReq = 0x14 - sysSizeofICMPFilter = 0x20 -) - -type sysPacketInfo struct { - IP [16]byte - IfIndex uint32 -} - -type sysMulticastReq struct { - IP [16]byte - IfIndex uint32 -} diff --git a/ipv6/sys_bsd.go b/ipv6/sys_bsd.go index 9e2ef4b0..226f5741 100644 --- a/ipv6/sys_bsd.go +++ b/ipv6/sys_bsd.go @@ -11,27 +11,38 @@ import ( "syscall" ) -// RFC 3542 options -const ( - // See /usr/include/netinet6/in6.h. - sysSockoptReceiveTrafficClass = syscall.IPV6_RECVTCLASS - sysSockoptTrafficClass = syscall.IPV6_TCLASS - sysSockoptReceiveHopLimit = syscall.IPV6_RECVHOPLIMIT - sysSockoptHopLimit = syscall.IPV6_HOPLIMIT - sysSockoptReceivePacketInfo = syscall.IPV6_RECVPKTINFO - sysSockoptPacketInfo = syscall.IPV6_PKTINFO - sysSockoptReceivePathMTU = syscall.IPV6_RECVPATHMTU - sysSockoptPathMTU = syscall.IPV6_PATHMTU - sysSockoptNextHop = syscall.IPV6_NEXTHOP - sysSockoptChecksum = syscall.IPV6_CHECKSUM +type sysSockoptLen int32 - // See /usr/include/netinet6/in6.h. - sysSockoptICMPFilter = 0x12 // syscall.ICMP6_FILTER +var ( + sockOpts = [ssoMax]sockOpt{ + ssoTrafficClass: {ianaProtocolIPv6, sysIPV6_TCLASS, ssoTypeInt}, + ssoHopLimit: {ianaProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt}, + ssoMulticastInterface: {ianaProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface}, + ssoMulticastHopLimit: {ianaProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt}, + ssoMulticastLoopback: {ianaProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt}, + ssoReceiveTrafficClass: {ianaProtocolIPv6, sysIPV6_RECVTCLASS, ssoTypeInt}, + ssoReceiveHopLimit: {ianaProtocolIPv6, sysIPV6_RECVHOPLIMIT, ssoTypeInt}, + ssoReceivePacketInfo: {ianaProtocolIPv6, sysIPV6_RECVPKTINFO, ssoTypeInt}, + ssoReceivePathMTU: {ianaProtocolIPv6, sysIPV6_RECVPATHMTU, ssoTypeInt}, + ssoPathMTU: {ianaProtocolIPv6, sysIPV6_PATHMTU, ssoTypeMTUInfo}, + ssoChecksum: {ianaProtocolIPv6, sysIPV6_CHECKSUM, ssoTypeInt}, + ssoICMPFilter: {ianaProtocolIPv6ICMP, sysICMP6_FILTER, ssoTypeICMPFilter}, + ssoJoinGroup: {ianaProtocolIPv6, sysIPV6_JOIN_GROUP, ssoTypeIPMreq}, + ssoLeaveGroup: {ianaProtocolIPv6, sysIPV6_LEAVE_GROUP, ssoTypeIPMreq}, + } ) -func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) { - sa.Len = syscall.SizeofSockaddrInet6 +func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) { + sa.Len = sysSizeofSockaddrInet6 sa.Family = syscall.AF_INET6 copy(sa.Addr[:], ip) - sa.Scope_id = uint32(ifindex) + 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) } diff --git a/ipv6/sys_darwin.go b/ipv6/sys_darwin.go index 418eb484..bc8cc31f 100644 --- a/ipv6/sys_darwin.go +++ b/ipv6/sys_darwin.go @@ -9,35 +9,63 @@ import ( "syscall" ) -// RFC 2292 options -const ( - // See /usr/include/netinet6/in6.h. - sysSockopt2292HopLimit = syscall.IPV6_2292HOPLIMIT - sysSockopt2292PacketInfo = syscall.IPV6_2292PKTINFO - sysSockopt2292NextHop = syscall.IPV6_2292NEXTHOP +type sysSockoptLen int32 + +var ( + sockOpts = [ssoMax]sockOpt{ + ssoTrafficClass: {ianaProtocolIPv6, sysIPV6_TCLASS, ssoTypeInt}, + ssoHopLimit: {ianaProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt}, + ssoMulticastInterface: {ianaProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface}, + ssoMulticastHopLimit: {ianaProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt}, + ssoMulticastLoopback: {ianaProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt}, + ssoReceiveHopLimit: {ianaProtocolIPv6, sysIPV6_2292HOPLIMIT, ssoTypeInt}, + ssoReceivePacketInfo: {ianaProtocolIPv6, sysIPV6_2292PKTINFO, ssoTypeInt}, + ssoChecksum: {ianaProtocolIPv6, sysIPV6_CHECKSUM, ssoTypeInt}, + ssoICMPFilter: {ianaProtocolIPv6ICMP, sysICMP6_FILTER, ssoTypeICMPFilter}, + ssoJoinGroup: {ianaProtocolIPv6, sysIPV6_JOIN_GROUP, ssoTypeIPMreq}, + ssoLeaveGroup: {ianaProtocolIPv6, sysIPV6_LEAVE_GROUP, ssoTypeIPMreq}, + } ) -// RFC 3542 options -const ( - // See /usr/include/netinet6/in6.h. - sysSockoptReceiveTrafficClass = 0x23 // IPV6_RECVTCLASS - sysSockoptTrafficClass = 0x24 // IPV6_TCLASS - sysSockoptReceiveHopLimit = 0x25 // IPV6_RECVHOPLIMIT - sysSockoptHopLimit = 0x2f // IPV6_HOPLIMIT - sysSockoptReceivePacketInfo = 0x3d // IPV6_RECVPKTINFO - sysSockoptPacketInfo = 0x2e // IPV6_PKTINFO - sysSockoptReceivePathMTU = 0x2b // IPV6_RECVPATHMTU - sysSockoptPathMTU = 0x2c // IPV6_PATHMTU - sysSockoptNextHop = 0x30 // IPV6_NEXTHOP - sysSockoptChecksum = 0x1a // IPV6_CHECKSUM +func init() { + // Seems like kern.osreldate is veiled on latest OS X. We use + // kern.osrelease instead. + osver, err := syscall.Sysctl("kern.osrelease") + if err != nil { + return + } + var i int + for i = range osver { + if osver[i] != '.' { + continue + } + } + // The IPV6_RECVPATHMTU and IPV6_PATHMTU options were + // introduced in OS X 10.7 (Darwin 11.0.0). + // See http://support.apple.com/kb/HT1633. + if i > 2 || i == 2 && osver[0] >= '1' && osver[1] >= '1' { + sockOpts[ssoReceivePathMTU].level = ianaProtocolIPv6 + sockOpts[ssoReceivePathMTU].name = sysIPV6_RECVPATHMTU + sockOpts[ssoReceivePathMTU].typ = ssoTypeInt + // Please be informed that IPV6_PATHMTU option will be + // a cause of kernel crash on 10.9 and earlier. + //sockOpts[ssoPathMTU].level = ianaProtocolIPv6 + //sockOpts[ssoPathMTU].name = sysIPV6_PATHMTU + //sockOpts[ssoPathMTU].typ = ssoTypeMTUInfo + } +} - // See /usr/include/netinet6/in6.h. - sysSockoptICMPFilter = 0x12 // ICMP6_FILTER -) - -func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) { - sa.Len = syscall.SizeofSockaddrInet6 +func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) { + sa.Len = sysSizeofSockaddrInet6 sa.Family = syscall.AF_INET6 copy(sa.Addr[:], ip) - sa.Scope_id = uint32(ifindex) + 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) } diff --git a/ipv6/sys_linux.go b/ipv6/sys_linux.go index e711f004..c2b4dde8 100644 --- a/ipv6/sys_linux.go +++ b/ipv6/sys_linux.go @@ -9,26 +9,37 @@ import ( "syscall" ) -// RFC 3542 options -const ( - // See /usr/include/linux/ipv6.h,in6.h. - sysSockoptReceiveTrafficClass = syscall.IPV6_RECVTCLASS - sysSockoptTrafficClass = syscall.IPV6_TCLASS - sysSockoptReceiveHopLimit = syscall.IPV6_RECVHOPLIMIT - sysSockoptHopLimit = syscall.IPV6_HOPLIMIT - sysSockoptReceivePacketInfo = syscall.IPV6_RECVPKTINFO - sysSockoptPacketInfo = syscall.IPV6_PKTINFO - sysSockoptReceivePathMTU = 0x3c // IPV6_RECVPATHMTU - sysSockoptPathMTU = 0x3d // IPV6_PATHMTU - sysSockoptNextHop = syscall.IPV6_NEXTHOP - sysSockoptChecksum = syscall.IPV6_CHECKSUM +type sysSockoptLen int32 - // See /usr/include/linux/icmpv6.h. - sysSockoptICMPFilter = 0x1 // syscall.ICMPV6_FILTER +var ( + sockOpts = [ssoMax]sockOpt{ + ssoTrafficClass: {ianaProtocolIPv6, sysIPV6_TCLASS, ssoTypeInt}, + ssoHopLimit: {ianaProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt}, + ssoMulticastInterface: {ianaProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface}, + ssoMulticastHopLimit: {ianaProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt}, + ssoMulticastLoopback: {ianaProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt}, + ssoReceiveTrafficClass: {ianaProtocolIPv6, sysIPV6_RECVTCLASS, ssoTypeInt}, + ssoReceiveHopLimit: {ianaProtocolIPv6, sysIPV6_RECVHOPLIMIT, ssoTypeInt}, + ssoReceivePacketInfo: {ianaProtocolIPv6, sysIPV6_RECVPKTINFO, ssoTypeInt}, + ssoReceivePathMTU: {ianaProtocolIPv6, sysIPV6_RECVPATHMTU, ssoTypeInt}, + ssoPathMTU: {ianaProtocolIPv6, sysIPV6_PATHMTU, ssoTypeMTUInfo}, + ssoChecksum: {ianaProtocolReserved, sysIPV6_CHECKSUM, ssoTypeInt}, + ssoICMPFilter: {ianaProtocolIPv6ICMP, sysICMPV6_FILTER, ssoTypeICMPFilter}, + ssoJoinGroup: {ianaProtocolIPv6, sysIPV6_ADD_MEMBERSHIP, ssoTypeIPMreq}, + ssoLeaveGroup: {ianaProtocolIPv6, sysIPV6_DROP_MEMBERSHIP, ssoTypeIPMreq}, + } ) -func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) { +func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) { sa.Family = syscall.AF_INET6 copy(sa.Addr[:], ip) - sa.Scope_id = uint32(ifindex) + sa.Scope_id = uint32(i) +} + +func (pi *sysInet6Pktinfo) setIfindex(i int) { + pi.Ifindex = int32(i) +} + +func (mreq *sysIPv6Mreq) setIfindex(i int) { + mreq.Ifindex = int32(i) } diff --git a/ipv6/sys_stub.go b/ipv6/sys_stub.go new file mode 100644 index 00000000..bc592690 --- /dev/null +++ b/ipv6/sys_stub.go @@ -0,0 +1,13 @@ +// 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 nacl plan9 solaris + +package ipv6 + +type sysSockoptLen int32 + +var ( + sockOpts = [ssoMax]sockOpt{} +) diff --git a/ipv6/sys_unix.go b/ipv6/sys_unix.go deleted file mode 100644 index fc5b00d2..00000000 --- a/ipv6/sys_unix.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2013 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 - -package ipv6 - -import "syscall" - -// RFC 3493 options -const ( - sysSockoptUnicastHopLimit = syscall.IPV6_UNICAST_HOPS - sysSockoptMulticastHopLimit = syscall.IPV6_MULTICAST_HOPS - sysSockoptMulticastInterface = syscall.IPV6_MULTICAST_IF - sysSockoptMulticastLoopback = syscall.IPV6_MULTICAST_LOOP - sysSockoptJoinGroup = syscall.IPV6_JOIN_GROUP - sysSockoptLeaveGroup = syscall.IPV6_LEAVE_GROUP -) - -const sysSizeofMTUInfo = 0x20 - -type sysMTUInfo struct { - Addr syscall.RawSockaddrInet6 - MTU uint32 -} diff --git a/ipv6/sys_windows.go b/ipv6/sys_windows.go index 9fef66a5..83b746fe 100644 --- a/ipv6/sys_windows.go +++ b/ipv6/sys_windows.go @@ -9,25 +9,51 @@ import ( "syscall" ) -// RFC 3493 options const ( // See ws2tcpip.h. - sysSockoptUnicastHopLimit = syscall.IPV6_UNICAST_HOPS - sysSockoptMulticastHopLimit = syscall.IPV6_MULTICAST_HOPS - sysSockoptMulticastInterface = syscall.IPV6_MULTICAST_IF - sysSockoptMulticastLoopback = syscall.IPV6_MULTICAST_LOOP - sysSockoptJoinGroup = syscall.IPV6_JOIN_GROUP - sysSockoptLeaveGroup = syscall.IPV6_LEAVE_GROUP + sysIPV6_UNICAST_HOPS = 0x4 + sysIPV6_MULTICAST_IF = 0x9 + sysIPV6_MULTICAST_HOPS = 0xa + sysIPV6_MULTICAST_LOOP = 0xb + sysIPV6_JOIN_GROUP = 0xc + sysIPV6_LEAVE_GROUP = 0xd + sysIPV6_PKTINFO = 0x13 + + sysSizeofSockaddrInet6 = 0x1c + + sysSizeofIPv6Mreq = 0x14 ) -// RFC 3542 options -const ( - // See ws2tcpip.h. - sysSockoptPacketInfo = 0x13 // IPV6_PKTINFO +type sysSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +var ( + sockOpts = [ssoMax]sockOpt{ + ssoHopLimit: {ianaProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt}, + ssoMulticastInterface: {ianaProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface}, + ssoMulticastHopLimit: {ianaProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt}, + ssoMulticastLoopback: {ianaProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt}, + ssoJoinGroup: {ianaProtocolIPv6, sysIPV6_JOIN_GROUP, ssoTypeIPMreq}, + ssoLeaveGroup: {ianaProtocolIPv6, sysIPV6_LEAVE_GROUP, ssoTypeIPMreq}, + } ) -func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) { +func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) { sa.Family = syscall.AF_INET6 copy(sa.Addr[:], ip) - sa.Scope_id = uint32(ifindex) + sa.Scope_id = uint32(i) +} + +func (mreq *sysIPv6Mreq) setIfindex(i int) { + mreq.Interface = uint32(i) }