Files
lneto/ethernet/crc.go
T

48 lines
1.4 KiB
Go

package ethernet
import (
"encoding/binary"
"hash/crc32"
)
//
// CRC API.
//
// crcTable is the IEEE CRC-32 table used for Ethernet FCS calculation.
var crcTable = crc32.MakeTable(crc32.IEEE)
// CRC32 calculates the Ethernet Frame Check Sequence (FCS) for the given data.
// The CRC is computed using the IEEE 802.3 CRC-32 polynomial.
// The input should be the frame data from destination MAC through payload,
// excluding any existing FCS.
func CRC32(data []byte) uint32 {
return crc32.Checksum(data, crcTable)
}
// CRC32Search searches for a valid CRC32 in data starting from minOffCRC.
// It computes the CRC incrementally from minOffCRC, checking at each position
// if the CRC matches the next 4 bytes (little-endian FCS).
// Returns the offset where a valid CRC was found, or -1 if no valid CRC exists.
// This is useful when the exact frame length is unknown but bounded by minOffCRC.
func CRC32Search(data []byte, minOffCRC int) (foundOffOrNegative int) {
if minOffCRC < 0 {
minOffCRC = 0
}
if len(data) < minOffCRC+4 {
return -1
}
// Calculate CRC up to minOffCRC
crc := crc32.Checksum(data[:minOffCRC], crcTable)
// Incrementally extend and check at each position
for off := minOffCRC; off <= len(data)-4; off++ {
got := binary.LittleEndian.Uint32(data[off:])
if crc == got {
return off
}
// Extend CRC by one byte for next iteration
crc = crc32.Update(crc, crcTable, data[off:off+1])
}
return -1
}