control_rfc3542_unix.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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
  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. // TODO(mikio): fix potential misaligned memory access
  19. *(*int32)(unsafe.Pointer(&data[:4][0])) = int32(cm.TrafficClass)
  20. }
  21. return b[syscall.CmsgSpace(4):]
  22. }
  23. func parseTrafficClass(cm *ControlMessage, b []byte) {
  24. // TODO(mikio): fix potential misaligned memory access
  25. cm.TrafficClass = int(*(*int32)(unsafe.Pointer(&b[:4][0])))
  26. }
  27. func marshalHopLimit(b []byte, cm *ControlMessage) []byte {
  28. m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
  29. m.Level = iana.ProtocolIPv6
  30. m.Type = sysIPV6_HOPLIMIT
  31. m.SetLen(syscall.CmsgLen(4))
  32. if cm != nil {
  33. data := b[syscall.CmsgLen(0):]
  34. // TODO(mikio): fix potential misaligned memory access
  35. *(*int32)(unsafe.Pointer(&data[:4][0])) = int32(cm.HopLimit)
  36. }
  37. return b[syscall.CmsgSpace(4):]
  38. }
  39. func parseHopLimit(cm *ControlMessage, b []byte) {
  40. // TODO(mikio): fix potential misaligned memory access
  41. cm.HopLimit = int(*(*int32)(unsafe.Pointer(&b[:4][0])))
  42. }
  43. func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
  44. m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
  45. m.Level = iana.ProtocolIPv6
  46. m.Type = sysIPV6_PKTINFO
  47. m.SetLen(syscall.CmsgLen(sysSizeofInet6Pktinfo))
  48. if cm != nil {
  49. pi := (*sysInet6Pktinfo)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
  50. if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
  51. copy(pi.Addr[:], ip)
  52. }
  53. if cm.IfIndex > 0 {
  54. pi.setIfindex(cm.IfIndex)
  55. }
  56. }
  57. return b[syscall.CmsgSpace(sysSizeofInet6Pktinfo):]
  58. }
  59. func parsePacketInfo(cm *ControlMessage, b []byte) {
  60. pi := (*sysInet6Pktinfo)(unsafe.Pointer(&b[0]))
  61. cm.Dst = pi.Addr[:]
  62. cm.IfIndex = int(pi.Ifindex)
  63. }
  64. func marshalNextHop(b []byte, cm *ControlMessage) []byte {
  65. m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
  66. m.Level = iana.ProtocolIPv6
  67. m.Type = sysIPV6_NEXTHOP
  68. m.SetLen(syscall.CmsgLen(sysSizeofSockaddrInet6))
  69. if cm != nil {
  70. sa := (*sysSockaddrInet6)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
  71. sa.setSockaddr(cm.NextHop, cm.IfIndex)
  72. }
  73. return b[syscall.CmsgSpace(sysSizeofSockaddrInet6):]
  74. }
  75. func parseNextHop(cm *ControlMessage, b []byte) {
  76. }
  77. func marshalPathMTU(b []byte, cm *ControlMessage) []byte {
  78. m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
  79. m.Level = iana.ProtocolIPv6
  80. m.Type = sysIPV6_PATHMTU
  81. m.SetLen(syscall.CmsgLen(sysSizeofIPv6Mtuinfo))
  82. return b[syscall.CmsgSpace(sysSizeofIPv6Mtuinfo):]
  83. }
  84. func parsePathMTU(cm *ControlMessage, b []byte) {
  85. mi := (*sysIPv6Mtuinfo)(unsafe.Pointer(&b[0]))
  86. cm.Dst = mi.Addr.Addr[:]
  87. cm.IfIndex = int(mi.Addr.Scope_id)
  88. cm.MTU = int(mi.Mtu)
  89. }