mirror of
https://github.com/SagerNet/sing-tun.git
synced 2025-04-02 19:37:40 +03:00
141 lines
2.7 KiB
Go
141 lines
2.7 KiB
Go
package clashtcpip
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"net/netip"
|
|
)
|
|
|
|
const (
|
|
versTCFL = 0
|
|
|
|
IPv6PayloadLenOffset = 4
|
|
|
|
IPv6NextHeaderOffset = 6
|
|
hopLimit = 7
|
|
v6SrcAddr = 8
|
|
v6DstAddr = v6SrcAddr + IPv6AddressSize
|
|
|
|
IPv6FixedHeaderSize = v6DstAddr + IPv6AddressSize
|
|
)
|
|
|
|
const (
|
|
versIHL = 0
|
|
tos = 1
|
|
ipVersionShift = 4
|
|
ipIHLMask = 0x0f
|
|
IPv4IHLStride = 4
|
|
)
|
|
|
|
type IPv6Packet []byte
|
|
|
|
const (
|
|
IPv6MinimumSize = IPv6FixedHeaderSize
|
|
|
|
IPv6AddressSize = 16
|
|
|
|
IPv6Version = 6
|
|
|
|
IPv6MinimumMTU = 1280
|
|
)
|
|
|
|
func (b IPv6Packet) PayloadLength() uint16 {
|
|
return binary.BigEndian.Uint16(b[IPv6PayloadLenOffset:])
|
|
}
|
|
|
|
func (b IPv6Packet) HopLimit() uint8 {
|
|
return b[hopLimit]
|
|
}
|
|
|
|
func (b IPv6Packet) NextHeader() byte {
|
|
return b[IPv6NextHeaderOffset]
|
|
}
|
|
|
|
func (b IPv6Packet) Protocol() IPProtocol {
|
|
return b.NextHeader()
|
|
}
|
|
|
|
func (b IPv6Packet) Payload() []byte {
|
|
return b[IPv6MinimumSize:][:b.PayloadLength()]
|
|
}
|
|
|
|
func (b IPv6Packet) SourceIP() netip.Addr {
|
|
addr, _ := netip.AddrFromSlice(b[v6SrcAddr:][:IPv6AddressSize])
|
|
return addr
|
|
}
|
|
|
|
func (b IPv6Packet) DestinationIP() netip.Addr {
|
|
addr, _ := netip.AddrFromSlice(b[v6DstAddr:][:IPv6AddressSize])
|
|
return addr
|
|
}
|
|
|
|
func (IPv6Packet) Checksum() uint16 {
|
|
return 0
|
|
}
|
|
|
|
func (b IPv6Packet) TOS() (uint8, uint32) {
|
|
v := binary.BigEndian.Uint32(b[versTCFL:])
|
|
return uint8(v >> 20), v & 0xfffff
|
|
}
|
|
|
|
func (b IPv6Packet) SetTOS(t uint8, l uint32) {
|
|
vtf := (6 << 28) | (uint32(t) << 20) | (l & 0xfffff)
|
|
binary.BigEndian.PutUint32(b[versTCFL:], vtf)
|
|
}
|
|
|
|
func (b IPv6Packet) SetPayloadLength(payloadLength uint16) {
|
|
binary.BigEndian.PutUint16(b[IPv6PayloadLenOffset:], payloadLength)
|
|
}
|
|
|
|
func (b IPv6Packet) SetSourceIP(addr netip.Addr) {
|
|
if addr.Is6() {
|
|
copy(b[v6SrcAddr:][:IPv6AddressSize], addr.AsSlice())
|
|
}
|
|
}
|
|
|
|
func (b IPv6Packet) SetDestinationIP(addr netip.Addr) {
|
|
if addr.Is6() {
|
|
copy(b[v6DstAddr:][:IPv6AddressSize], addr.AsSlice())
|
|
}
|
|
}
|
|
|
|
func (b IPv6Packet) SetHopLimit(v uint8) {
|
|
b[hopLimit] = v
|
|
}
|
|
|
|
func (b IPv6Packet) SetNextHeader(v byte) {
|
|
b[IPv6NextHeaderOffset] = v
|
|
}
|
|
|
|
func (b IPv6Packet) SetProtocol(p IPProtocol) {
|
|
b.SetNextHeader(p)
|
|
}
|
|
|
|
func (b IPv6Packet) DecTimeToLive() {
|
|
b[hopLimit] = b[hopLimit] - uint8(1)
|
|
}
|
|
|
|
func (IPv6Packet) SetChecksum(uint16) {
|
|
}
|
|
|
|
func (IPv6Packet) ResetChecksum() {
|
|
}
|
|
|
|
func (b IPv6Packet) PseudoSum() uint32 {
|
|
sum := Sum(b[v6SrcAddr:IPv6FixedHeaderSize])
|
|
sum += uint32(b.Protocol())
|
|
sum += uint32(b.PayloadLength())
|
|
return sum
|
|
}
|
|
|
|
func (b IPv6Packet) Valid() bool {
|
|
return len(b) >= IPv6MinimumSize && len(b) >= int(b.PayloadLength())+IPv6MinimumSize
|
|
}
|
|
|
|
func IPVersion(b []byte) int {
|
|
if len(b) < versIHL+1 {
|
|
return -1
|
|
}
|
|
return int(b[versIHL] >> ipVersionShift)
|
|
}
|
|
|
|
var _ IP = (*IPv6Packet)(nil)
|