control_rfc3542_unix.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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. 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(sysSizeofInet6Pktinfo))
  44. if cm != nil {
  45. pi := (*sysInet6Pktinfo)(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(sysSizeofInet6Pktinfo):]
  54. }
  55. func parsePacketInfo(cm *ControlMessage, b []byte) {
  56. pi := (*sysInet6Pktinfo)(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(sysSizeofSockaddrInet6))
  65. if cm != nil {
  66. sa := (*sysSockaddrInet6)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
  67. sa.setSockaddr(cm.NextHop, cm.IfIndex)
  68. }
  69. return b[syscall.CmsgSpace(sysSizeofSockaddrInet6):]
  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(sysSizeofIPv6Mtuinfo))
  78. return b[syscall.CmsgSpace(sysSizeofIPv6Mtuinfo):]
  79. }
  80. func parsePathMTU(cm *ControlMessage, b []byte) {
  81. mi := (*sysIPv6Mtuinfo)(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. }