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 5//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos 6// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos 7 8package ipv6 9 10import ( 11 "net" 12 "unsafe" 13 14 "golang.org/x/net/internal/iana" 15 "golang.org/x/net/internal/socket" 16 17 "golang.org/x/sys/unix" 18) 19 20func marshalTrafficClass(b []byte, cm *ControlMessage) []byte { 21 m := socket.ControlMessage(b) 22 m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_TCLASS, 4) 23 if cm != nil { 24 socket.NativeEndian.PutUint32(m.Data(4), uint32(cm.TrafficClass)) 25 } 26 return m.Next(4) 27} 28 29func parseTrafficClass(cm *ControlMessage, b []byte) { 30 cm.TrafficClass = int(socket.NativeEndian.Uint32(b[:4])) 31} 32 33func marshalHopLimit(b []byte, cm *ControlMessage) []byte { 34 m := socket.ControlMessage(b) 35 m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_HOPLIMIT, 4) 36 if cm != nil { 37 socket.NativeEndian.PutUint32(m.Data(4), uint32(cm.HopLimit)) 38 } 39 return m.Next(4) 40} 41 42func parseHopLimit(cm *ControlMessage, b []byte) { 43 cm.HopLimit = int(socket.NativeEndian.Uint32(b[:4])) 44} 45 46func marshalPacketInfo(b []byte, cm *ControlMessage) []byte { 47 m := socket.ControlMessage(b) 48 m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_PKTINFO, sizeofInet6Pktinfo) 49 if cm != nil { 50 pi := (*inet6Pktinfo)(unsafe.Pointer(&m.Data(sizeofInet6Pktinfo)[0])) 51 if ip := cm.Src.To16(); ip != nil && ip.To4() == nil { 52 copy(pi.Addr[:], ip) 53 } 54 if cm.IfIndex > 0 { 55 pi.setIfindex(cm.IfIndex) 56 } 57 } 58 return m.Next(sizeofInet6Pktinfo) 59} 60 61func parsePacketInfo(cm *ControlMessage, b []byte) { 62 pi := (*inet6Pktinfo)(unsafe.Pointer(&b[0])) 63 if len(cm.Dst) < net.IPv6len { 64 cm.Dst = make(net.IP, net.IPv6len) 65 } 66 copy(cm.Dst, pi.Addr[:]) 67 cm.IfIndex = int(pi.Ifindex) 68} 69 70func marshalNextHop(b []byte, cm *ControlMessage) []byte { 71 m := socket.ControlMessage(b) 72 m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_NEXTHOP, sizeofSockaddrInet6) 73 if cm != nil { 74 sa := (*sockaddrInet6)(unsafe.Pointer(&m.Data(sizeofSockaddrInet6)[0])) 75 sa.setSockaddr(cm.NextHop, cm.IfIndex) 76 } 77 return m.Next(sizeofSockaddrInet6) 78} 79 80func parseNextHop(cm *ControlMessage, b []byte) { 81} 82 83func marshalPathMTU(b []byte, cm *ControlMessage) []byte { 84 m := socket.ControlMessage(b) 85 m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo) 86 return m.Next(sizeofIPv6Mtuinfo) 87} 88 89func parsePathMTU(cm *ControlMessage, b []byte) { 90 mi := (*ipv6Mtuinfo)(unsafe.Pointer(&b[0])) 91 if len(cm.Dst) < net.IPv6len { 92 cm.Dst = make(net.IP, net.IPv6len) 93 } 94 copy(cm.Dst, mi.Addr.Addr[:]) 95 cm.IfIndex = int(mi.Addr.Scope_id) 96 cm.MTU = int(mi.Mtu) 97} 98