mirror of
https://github.com/soypat/lneto.git
synced 2026-08-07 16:33:40 +00:00
48 lines
1.4 KiB
Go
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
|
|
}
|