Add tracked vpnruntime implementation for CI guard tests
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
package vpnruntime
|
||||
|
||||
import "encoding/binary"
|
||||
|
||||
func normalizeIPv4PacketChecksums(packet []byte) bool {
|
||||
if len(packet) < 20 || packet[0]>>4 != 4 {
|
||||
return false
|
||||
}
|
||||
ihl := int(packet[0]&0x0f) * 4
|
||||
if ihl < 20 || len(packet) < ihl {
|
||||
return false
|
||||
}
|
||||
totalLen := int(binary.BigEndian.Uint16(packet[2:4]))
|
||||
if totalLen <= 0 || totalLen > len(packet) {
|
||||
totalLen = len(packet)
|
||||
}
|
||||
if totalLen < ihl {
|
||||
return false
|
||||
}
|
||||
|
||||
packet[10], packet[11] = 0, 0
|
||||
binary.BigEndian.PutUint16(packet[10:12], checksum(packet[:ihl]))
|
||||
|
||||
proto := packet[9]
|
||||
payload := packet[ihl:totalLen]
|
||||
switch proto {
|
||||
case 6:
|
||||
if len(payload) < 20 {
|
||||
return true
|
||||
}
|
||||
payload[16], payload[17] = 0, 0
|
||||
binary.BigEndian.PutUint16(payload[16:18], transportChecksum(packet, payload, proto))
|
||||
case 17:
|
||||
if len(payload) < 8 {
|
||||
return true
|
||||
}
|
||||
payload[6], payload[7] = 0, 0
|
||||
sum := transportChecksum(packet, payload, proto)
|
||||
if sum == 0 {
|
||||
sum = 0xffff
|
||||
}
|
||||
binary.BigEndian.PutUint16(payload[6:8], sum)
|
||||
case 1:
|
||||
if len(payload) < 4 {
|
||||
return true
|
||||
}
|
||||
payload[2], payload[3] = 0, 0
|
||||
binary.BigEndian.PutUint16(payload[2:4], checksum(payload))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func transportChecksum(ipHeader []byte, payload []byte, proto byte) uint16 {
|
||||
pseudo := make([]byte, 12+len(payload))
|
||||
copy(pseudo[0:4], ipHeader[12:16])
|
||||
copy(pseudo[4:8], ipHeader[16:20])
|
||||
pseudo[8] = 0
|
||||
pseudo[9] = proto
|
||||
binary.BigEndian.PutUint16(pseudo[10:12], uint16(len(payload)))
|
||||
copy(pseudo[12:], payload)
|
||||
return checksum(pseudo)
|
||||
}
|
||||
|
||||
func checksum(data []byte) uint16 {
|
||||
var sum uint32
|
||||
for len(data) >= 2 {
|
||||
sum += uint32(binary.BigEndian.Uint16(data[:2]))
|
||||
data = data[2:]
|
||||
}
|
||||
if len(data) == 1 {
|
||||
sum += uint32(data[0]) << 8
|
||||
}
|
||||
for (sum >> 16) != 0 {
|
||||
sum = (sum & 0xffff) + (sum >> 16)
|
||||
}
|
||||
return ^uint16(sum)
|
||||
}
|
||||
Reference in New Issue
Block a user