I need to implement error checking for an ethernet frame. How can I implement this?
I have gone through a few documents to understand how to check that an ethernet frame is valid. I tried to implement the algorithm described on the wikipedia page (in swift 5.1) :
// we run the calculation over all the frame except the CRC itself (last 4 bytes)
var crc : UInt32 = 0xFFFFFFFF
for x in 0..<(packetLength-4) {
let byte = packetBytes[x]
let nLookupIndex : UInt32 = (crc ^ byte) & 0xFF
crc = (crc >> 8) ^ crcTable[Int(nLookupIndex)]
}
// This is the end padding (adding 4 bytes with 0 at the end)
for x in 0..<4 {
let byte : UInt32 = 0
let nLookupIndex : UInt32 = (crc ^ byte) & 0xFF
crc = (crc >> 8) ^ crcTable[Int(nLookupIndex)]
}
where the crcTable looks like this:
let crcTable = [0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, .... 0x5a05df1b, 0x2d02ef8d]
I can see that this is wrong, because it does not give me the crc that I see on ethernet frames. Is anyone able to point towards what I am doing wrong?
Include the data and CRC in the calculation. Since the CRC is post complemented, a recalculation of the CRC will be a non-zero constant, 0x2144DF1C.
Change the code to:
var crc : UInt32 = 0xFFFFFFFF
for x in 0..<(packetLength) { // fix
let byte = packetBytes[x]
let nLookupIndex : UInt32 = (crc ^ byte) & 0xFF
crc = (crc >> 8) ^ crcTable[Int(nLookupIndex)]
}
if (crc != 0x2144DF1C){ // if CRC != 0x2144DF1C
// ... // it is bad CRC
}
Whenever a CRC is post complemented, a recalculation of CRC of data plus the CRC will result in a non-zero constant, in this case, 0x2144DF1C (if the CRC is not post complemented, the recalculated CRC will be zero).
User contributions licensed under CC BY-SA 3.0