github.com/metacubex/sing-tun@v0.2.7-0.20240512075008-89e7c6208eec/internal/clashtcpip/ipv6.go (about)

     1  package clashtcpip
     2  
     3  import (
     4  	"encoding/binary"
     5  	"net/netip"
     6  )
     7  
     8  const (
     9  	versTCFL = 0
    10  
    11  	IPv6PayloadLenOffset = 4
    12  
    13  	IPv6NextHeaderOffset = 6
    14  	hopLimit             = 7
    15  	v6SrcAddr            = 8
    16  	v6DstAddr            = v6SrcAddr + IPv6AddressSize
    17  
    18  	IPv6FixedHeaderSize = v6DstAddr + IPv6AddressSize
    19  )
    20  
    21  const (
    22  	versIHL        = 0
    23  	tos            = 1
    24  	ipVersionShift = 4
    25  	ipIHLMask      = 0x0f
    26  	IPv4IHLStride  = 4
    27  )
    28  
    29  type IPv6Packet []byte
    30  
    31  const (
    32  	IPv6MinimumSize = IPv6FixedHeaderSize
    33  
    34  	IPv6AddressSize = 16
    35  
    36  	IPv6Version = 6
    37  
    38  	IPv6MinimumMTU = 1280
    39  )
    40  
    41  func (b IPv6Packet) PayloadLength() uint16 {
    42  	return binary.BigEndian.Uint16(b[IPv6PayloadLenOffset:])
    43  }
    44  
    45  func (b IPv6Packet) HopLimit() uint8 {
    46  	return b[hopLimit]
    47  }
    48  
    49  func (b IPv6Packet) NextHeader() byte {
    50  	return b[IPv6NextHeaderOffset]
    51  }
    52  
    53  func (b IPv6Packet) Protocol() IPProtocol {
    54  	return b.NextHeader()
    55  }
    56  
    57  func (b IPv6Packet) Payload() []byte {
    58  	return b[IPv6MinimumSize:][:b.PayloadLength()]
    59  }
    60  
    61  func (b IPv6Packet) SourceIP() netip.Addr {
    62  	addr, _ := netip.AddrFromSlice(b[v6SrcAddr:][:IPv6AddressSize])
    63  	return addr
    64  }
    65  
    66  func (b IPv6Packet) DestinationIP() netip.Addr {
    67  	addr, _ := netip.AddrFromSlice(b[v6DstAddr:][:IPv6AddressSize])
    68  	return addr
    69  }
    70  
    71  func (IPv6Packet) Checksum() uint16 {
    72  	return 0
    73  }
    74  
    75  func (b IPv6Packet) TOS() (uint8, uint32) {
    76  	v := binary.BigEndian.Uint32(b[versTCFL:])
    77  	return uint8(v >> 20), v & 0xfffff
    78  }
    79  
    80  func (b IPv6Packet) SetTOS(t uint8, l uint32) {
    81  	vtf := (6 << 28) | (uint32(t) << 20) | (l & 0xfffff)
    82  	binary.BigEndian.PutUint32(b[versTCFL:], vtf)
    83  }
    84  
    85  func (b IPv6Packet) SetPayloadLength(payloadLength uint16) {
    86  	binary.BigEndian.PutUint16(b[IPv6PayloadLenOffset:], payloadLength)
    87  }
    88  
    89  func (b IPv6Packet) SetSourceIP(addr netip.Addr) {
    90  	if addr.Is6() {
    91  		copy(b[v6SrcAddr:][:IPv6AddressSize], addr.AsSlice())
    92  	}
    93  }
    94  
    95  func (b IPv6Packet) SetDestinationIP(addr netip.Addr) {
    96  	if addr.Is6() {
    97  		copy(b[v6DstAddr:][:IPv6AddressSize], addr.AsSlice())
    98  	}
    99  }
   100  
   101  func (b IPv6Packet) SetHopLimit(v uint8) {
   102  	b[hopLimit] = v
   103  }
   104  
   105  func (b IPv6Packet) SetNextHeader(v byte) {
   106  	b[IPv6NextHeaderOffset] = v
   107  }
   108  
   109  func (b IPv6Packet) SetProtocol(p IPProtocol) {
   110  	b.SetNextHeader(p)
   111  }
   112  
   113  func (b IPv6Packet) DecTimeToLive() {
   114  	b[hopLimit] = b[hopLimit] - uint8(1)
   115  }
   116  
   117  func (IPv6Packet) SetChecksum(uint16) {
   118  }
   119  
   120  func (IPv6Packet) ResetChecksum() {
   121  }
   122  
   123  func (b IPv6Packet) PseudoSum() uint32 {
   124  	sum := Sum(b[v6SrcAddr:IPv6FixedHeaderSize])
   125  	sum += uint32(b.Protocol())
   126  	sum += uint32(b.PayloadLength())
   127  	return sum
   128  }
   129  
   130  func (b IPv6Packet) Valid() bool {
   131  	return len(b) >= IPv6MinimumSize && len(b) >= int(b.PayloadLength())+IPv6MinimumSize
   132  }
   133  
   134  func IPVersion(b []byte) int {
   135  	if len(b) < versIHL+1 {
   136  		return -1
   137  	}
   138  	return int(b[versIHL] >> ipVersionShift)
   139  }
   140  
   141  var _ IP = (*IPv6Packet)(nil)