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)