This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

Frame check sequence calculation

0

Hello,

I am trying to calculate the FCS for ipv4/ipv6 packets.

I use the following algorithm:

  1. I get the hex string of the whole frame (from ethernet layer to data incapsulated inside tcp/udp)
  2. I transform it into a binary string
  3. I negate the first 32 bits
  4. I reverse the order of the bits in each byte in the whole frame
  5. I xor the first 33 elements of the binary string with 100000100110000010001110110110111 and trim the left zeros
  6. I repeat step 5 until my binary string has a length less or equal to 32
  7. I negate all the bits
  8. I transform the binary string into a hex string

And that is my algorithm. Wireshark says it's wrong, and I'm sure he's right, but I don't know what I did wrong.

I learned about it here: http://cs.nju.edu.cn/yangxc/dcc_teach/fcs-calc.pdf

Any ideas?

asked 17 Jul '13, 06:22

Maio's gravatar image

Maio
11336
accept rate: 0%


One Answer:

0

The PDF mentions NTCIP and AB 3418.

Cite: NTCIP and AB 3418 protocol developers typically use the inverse polynomial method to calculate the Frame Check Sequence (FCS).

If you try to create an FCS for an ethernet frame with a method defined for NTCIP it may not work for one of the following reasons:

  • either: the FCS algorithm for ethernet is different. Then that's the reason for the discrepancy.
  • or: the FCS algorithm defined in the PDF (for NTCIP) is the same as for ethernet (I did not check). In that case, your implementation is buggy.

For a detailed information how to calculate the FCS please check the following file:

http://www.xilinx.com/support/documentation/application_notes/xapp209.pdf

You can also read the Wireshark source code:

packet-eth.c:add_ethernet_trailer()

        guint32 fcs = crc32_802_tvb(tvb, tvb_length(tvb) - 4);

crc32-tvb.c:

crc32_802_tvb(tvbuff_t *tvb, guint len)
{
    guint32 c_crc;
c_crc = crc32_ccitt_tvb(tvb, len);

/* Byte reverse. */ c_crc = GUINT32_SWAP_LE_BE(c_crc);

return ( c_crc );

}


Regards
Kurt

answered 17 Jul '13, 16:05

Kurt%20Knochner's gravatar image

Kurt Knochner ♦
24.8k1039237
accept rate: 15%

1

To my great surprise, "AB" in "AB 3418" stands for "Assembly Bill", as in "California Assembly BIll 3418" (I've lived here 28 years, so I should've recognized it :-)); that bill, passed by the California state legislature specified that traffic signal controllers in California installed in 1996 or later must have a standard control protocol; the California Department of Transportation published a specification for that protocol, which runs over 1200 baud RS-232.

The protocol was based on a draft of a US Department of Transportation(?) standard, the "National Transportation Control/ITS Communications Protocol" - that's "NTCIP". I infer from section 4.3.2 "Data Link Layer Protocol" of the CA DOT specification that it's based on HDLC, so the CRC would presumably be the one specified for HDLC.

The 32-bit HDLC CRC and the Ethernet CRC use the same polynomial; there might be a byte-order difference, however.

(17 Jul '13, 18:04) Guy Harris ♦♦