You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

106 lines
4.3 KiB

  1. // Copyright 2013 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package ipv6
  5. import (
  6. "net"
  7. "strconv"
  8. "strings"
  9. "syscall"
  10. "unsafe"
  11. "golang.org/x/net/internal/iana"
  12. )
  13. var (
  14. ctlOpts = [ctlMax]ctlOpt{
  15. ctlHopLimit: {sysIPV6_2292HOPLIMIT, 4, marshal2292HopLimit, parseHopLimit},
  16. ctlPacketInfo: {sysIPV6_2292PKTINFO, sizeofInet6Pktinfo, marshal2292PacketInfo, parsePacketInfo},
  17. }
  18. sockOpts = [ssoMax]sockOpt{
  19. ssoHopLimit: {iana.ProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt},
  20. ssoMulticastInterface: {iana.ProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface},
  21. ssoMulticastHopLimit: {iana.ProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt},
  22. ssoMulticastLoopback: {iana.ProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt},
  23. ssoReceiveHopLimit: {iana.ProtocolIPv6, sysIPV6_2292HOPLIMIT, ssoTypeInt},
  24. ssoReceivePacketInfo: {iana.ProtocolIPv6, sysIPV6_2292PKTINFO, ssoTypeInt},
  25. ssoChecksum: {iana.ProtocolIPv6, sysIPV6_CHECKSUM, ssoTypeInt},
  26. ssoICMPFilter: {iana.ProtocolIPv6ICMP, sysICMP6_FILTER, ssoTypeICMPFilter},
  27. ssoJoinGroup: {iana.ProtocolIPv6, sysIPV6_JOIN_GROUP, ssoTypeIPMreq},
  28. ssoLeaveGroup: {iana.ProtocolIPv6, sysIPV6_LEAVE_GROUP, ssoTypeIPMreq},
  29. }
  30. )
  31. func init() {
  32. // Seems like kern.osreldate is veiled on latest OS X. We use
  33. // kern.osrelease instead.
  34. s, err := syscall.Sysctl("kern.osrelease")
  35. if err != nil {
  36. return
  37. }
  38. ss := strings.Split(s, ".")
  39. if len(ss) == 0 {
  40. return
  41. }
  42. // The IP_PKTINFO and protocol-independent multicast API were
  43. // introduced in OS X 10.7 (Darwin 11). But it looks like
  44. // those features require OS X 10.8 (Darwin 12) or above.
  45. // See http://support.apple.com/kb/HT1633.
  46. if mjver, err := strconv.Atoi(ss[0]); err != nil || mjver < 12 {
  47. return
  48. }
  49. ctlOpts[ctlTrafficClass] = ctlOpt{sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass}
  50. ctlOpts[ctlHopLimit] = ctlOpt{sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit}
  51. ctlOpts[ctlPacketInfo] = ctlOpt{sysIPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo}
  52. ctlOpts[ctlNextHop] = ctlOpt{sysIPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop}
  53. ctlOpts[ctlPathMTU] = ctlOpt{sysIPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU}
  54. sockOpts[ssoTrafficClass] = sockOpt{iana.ProtocolIPv6, sysIPV6_TCLASS, ssoTypeInt}
  55. sockOpts[ssoReceiveTrafficClass] = sockOpt{iana.ProtocolIPv6, sysIPV6_RECVTCLASS, ssoTypeInt}
  56. sockOpts[ssoReceiveHopLimit] = sockOpt{iana.ProtocolIPv6, sysIPV6_RECVHOPLIMIT, ssoTypeInt}
  57. sockOpts[ssoReceivePacketInfo] = sockOpt{iana.ProtocolIPv6, sysIPV6_RECVPKTINFO, ssoTypeInt}
  58. sockOpts[ssoReceivePathMTU] = sockOpt{iana.ProtocolIPv6, sysIPV6_RECVPATHMTU, ssoTypeInt}
  59. sockOpts[ssoPathMTU] = sockOpt{iana.ProtocolIPv6, sysIPV6_PATHMTU, ssoTypeMTUInfo}
  60. sockOpts[ssoJoinGroup] = sockOpt{iana.ProtocolIPv6, sysMCAST_JOIN_GROUP, ssoTypeGroupReq}
  61. sockOpts[ssoLeaveGroup] = sockOpt{iana.ProtocolIPv6, sysMCAST_LEAVE_GROUP, ssoTypeGroupReq}
  62. sockOpts[ssoJoinSourceGroup] = sockOpt{iana.ProtocolIPv6, sysMCAST_JOIN_SOURCE_GROUP, ssoTypeGroupSourceReq}
  63. sockOpts[ssoLeaveSourceGroup] = sockOpt{iana.ProtocolIPv6, sysMCAST_LEAVE_SOURCE_GROUP, ssoTypeGroupSourceReq}
  64. sockOpts[ssoBlockSourceGroup] = sockOpt{iana.ProtocolIPv6, sysMCAST_BLOCK_SOURCE, ssoTypeGroupSourceReq}
  65. sockOpts[ssoUnblockSourceGroup] = sockOpt{iana.ProtocolIPv6, sysMCAST_UNBLOCK_SOURCE, ssoTypeGroupSourceReq}
  66. }
  67. func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
  68. sa.Len = sizeofSockaddrInet6
  69. sa.Family = syscall.AF_INET6
  70. copy(sa.Addr[:], ip)
  71. sa.Scope_id = uint32(i)
  72. }
  73. func (pi *inet6Pktinfo) setIfindex(i int) {
  74. pi.Ifindex = uint32(i)
  75. }
  76. func (mreq *ipv6Mreq) setIfindex(i int) {
  77. mreq.Interface = uint32(i)
  78. }
  79. func (gr *groupReq) setGroup(grp net.IP) {
  80. sa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4))
  81. sa.Len = sizeofSockaddrInet6
  82. sa.Family = syscall.AF_INET6
  83. copy(sa.Addr[:], grp)
  84. }
  85. func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
  86. sa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4))
  87. sa.Len = sizeofSockaddrInet6
  88. sa.Family = syscall.AF_INET6
  89. copy(sa.Addr[:], grp)
  90. sa = (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 132))
  91. sa.Len = sizeofSockaddrInet6
  92. sa.Family = syscall.AF_INET6
  93. copy(sa.Addr[:], src)
  94. }