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.
 
 
 

100 lines
2.7 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. // +build darwin dragonfly freebsd linux netbsd openbsd solaris
  5. package ipv6
  6. import (
  7. "syscall"
  8. "unsafe"
  9. "golang.org/x/net/internal/iana"
  10. )
  11. func marshalTrafficClass(b []byte, cm *ControlMessage) []byte {
  12. m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
  13. m.Level = iana.ProtocolIPv6
  14. m.Type = sysIPV6_TCLASS
  15. m.SetLen(syscall.CmsgLen(4))
  16. if cm != nil {
  17. data := b[syscall.CmsgLen(0):]
  18. nativeEndian.PutUint32(data[:4], uint32(cm.TrafficClass))
  19. }
  20. return b[syscall.CmsgSpace(4):]
  21. }
  22. func parseTrafficClass(cm *ControlMessage, b []byte) {
  23. cm.TrafficClass = int(nativeEndian.Uint32(b[:4]))
  24. }
  25. func marshalHopLimit(b []byte, cm *ControlMessage) []byte {
  26. m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
  27. m.Level = iana.ProtocolIPv6
  28. m.Type = sysIPV6_HOPLIMIT
  29. m.SetLen(syscall.CmsgLen(4))
  30. if cm != nil {
  31. data := b[syscall.CmsgLen(0):]
  32. nativeEndian.PutUint32(data[:4], uint32(cm.HopLimit))
  33. }
  34. return b[syscall.CmsgSpace(4):]
  35. }
  36. func parseHopLimit(cm *ControlMessage, b []byte) {
  37. cm.HopLimit = int(nativeEndian.Uint32(b[:4]))
  38. }
  39. func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
  40. m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
  41. m.Level = iana.ProtocolIPv6
  42. m.Type = sysIPV6_PKTINFO
  43. m.SetLen(syscall.CmsgLen(sizeofInet6Pktinfo))
  44. if cm != nil {
  45. pi := (*inet6Pktinfo)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
  46. if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
  47. copy(pi.Addr[:], ip)
  48. }
  49. if cm.IfIndex > 0 {
  50. pi.setIfindex(cm.IfIndex)
  51. }
  52. }
  53. return b[syscall.CmsgSpace(sizeofInet6Pktinfo):]
  54. }
  55. func parsePacketInfo(cm *ControlMessage, b []byte) {
  56. pi := (*inet6Pktinfo)(unsafe.Pointer(&b[0]))
  57. cm.Dst = pi.Addr[:]
  58. cm.IfIndex = int(pi.Ifindex)
  59. }
  60. func marshalNextHop(b []byte, cm *ControlMessage) []byte {
  61. m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
  62. m.Level = iana.ProtocolIPv6
  63. m.Type = sysIPV6_NEXTHOP
  64. m.SetLen(syscall.CmsgLen(sizeofSockaddrInet6))
  65. if cm != nil {
  66. sa := (*sockaddrInet6)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
  67. sa.setSockaddr(cm.NextHop, cm.IfIndex)
  68. }
  69. return b[syscall.CmsgSpace(sizeofSockaddrInet6):]
  70. }
  71. func parseNextHop(cm *ControlMessage, b []byte) {
  72. }
  73. func marshalPathMTU(b []byte, cm *ControlMessage) []byte {
  74. m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
  75. m.Level = iana.ProtocolIPv6
  76. m.Type = sysIPV6_PATHMTU
  77. m.SetLen(syscall.CmsgLen(sizeofIPv6Mtuinfo))
  78. return b[syscall.CmsgSpace(sizeofIPv6Mtuinfo):]
  79. }
  80. func parsePathMTU(cm *ControlMessage, b []byte) {
  81. mi := (*ipv6Mtuinfo)(unsafe.Pointer(&b[0]))
  82. cm.Dst = mi.Addr.Addr[:]
  83. cm.IfIndex = int(mi.Addr.Scope_id)
  84. cm.MTU = int(mi.Mtu)
  85. }