github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/net/ipv6/control_rfc3542_unix.go (about)

     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  
     8  package ipv6
     9  
    10  import (
    11  	"net"
    12  	"unsafe"
    13  
    14  	"github.com/hxx258456/ccgo/net/internal/iana"
    15  	"github.com/hxx258456/ccgo/net/internal/socket"
    16  
    17  	"golang.org/x/sys/unix"
    18  )
    19  
    20  func 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  
    29  func parseTrafficClass(cm *ControlMessage, b []byte) {
    30  	cm.TrafficClass = int(socket.NativeEndian.Uint32(b[:4]))
    31  }
    32  
    33  func 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  
    42  func parseHopLimit(cm *ControlMessage, b []byte) {
    43  	cm.HopLimit = int(socket.NativeEndian.Uint32(b[:4]))
    44  }
    45  
    46  func 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  
    61  func 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  
    70  func 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  
    80  func parseNextHop(cm *ControlMessage, b []byte) {
    81  }
    82  
    83  func 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  
    89  func 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  }