CRC Lab

In this laboratory, you will add CRC generation to the Ethernet Lab you finished previously.

Mod 2 arithmetic review

 1111         11001

+1010        x  101

=====        ======

 0101         11001

           +11001

            ========

            1111101

Error Control Coding

for an 32 bit code like the one we use for the CRC

T=(232)M+R 





where M is the message to be sent (Ethernet header and payload), R is the CRC field and T is the total Ethernet packet.

232M        R

---- = Q + -

P          P



where P is the CRC generating polonomial. After the division you are left with a quotient (Q) and remainder (R).

T   232M+R       R  R

- = ------ = Q+ - +- = Q

P     P         P  P



Since R+R=0 in mod 2 arithmetic.

Process

Derive R as the remainder and use this as the CRC in sending a packet. In decode divide T/P and if there is a remainder, then there was an error.

Polonomial

The polynomial you will be using is CRC-32 or x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1. It can correct single bit errors as well as multiple bit errors if the errors meet certain criteria.

This corresponds to a bit mask of 100000100110000010001110110110111.

CRC Generation

We can perform long division to generate the remainder (CRC).

You will probably want to do this at some time to test your code with simple cases (subtraction is the same as addition in mod 2 arithmetic).

Assume a Payload of 0x80. Sure, it's small, and this means that the src and dst addresses were zero, but you should be able to do the big ones by yourself.





                                                                            10000010

                                       ______________________________________________

10000010 01100000 10001110 11011011 1 | 10000000 00000000 00000000 00000000 00000000

                                        10000010 01100000 10001110 11011011 1

                                        ============

                                        00000010 01100000 10001110 11011011 10000000

                                              10 00001001 10000010 00111011 0110111 

                                        ============     

                                              00 01101001 00001100 11100000 11101110





                  R=01101001 00001100 11100000 11101110



The CRC field in the Ethernet packet will get this R value. In other words, the packet will have this CRC value following the payload.

On the receiving end, we can perform the same long division.

                                                                            10000010

                                       ______________________________________________

10000010 01100000 10001110 11011011 1 | 10000000 01101001 00001100 11100000 11101110

                                        10000010 01100000 10001110 11011011 1

                                        ============

                                        00000010 00001001 10000010 00111011 01101110

                                              10 00001001 10000010 00111011 0110111

                                        ============     

                                              00 00000000 00000000 00000000 0000000





                  R=00000000 00000000 00000000 0000000 





So it worked!! If the Remainder had been non-zero, then there would have been an error.

Shift Register Implementation

All of this long division seems kind of messy, particularly with large packets and you may have wondered how you would actually implement it in your program. Well, an alternate algorithm has been found using a shift register that generates exactly the same remainder values. The shift register is also used in hardware implementations of CRC. Most CRC generation is done with hardware, or with lookup tables because it is so computationally demanding.

The shift register is initialized to zero, when a non-zero value is present at x31, a one is XOR-ed with the value coming from the previous stage of the shift register at all points where the polynomial is non-zero.


crc example

This can be easily implemented in a program. This pseudo code should give you some ideas:

message = DATA, zero CRC

CRC = 0

for(i = 0 to length of message)

   

   if(CRC & 0x80000000)  /*if the most significant bit of the shift register is on, then recirculate the results*/

     domask = 1;



   CRC <<= 1;  

if(message[most significant bit])

CRC ^= 1


   if(domask)

      CRC ^= mask; /* mask is the pattern corresponding to the polynomial */


   domask = 0;



   message <<= 1; /* watch out, since the message is many bytes long, 

                   you will have to store it in a character array and do the shifts between bytes by hand */


        


Passoff:


The passoff procedure will test the following specific items


·
The lab code will generate packets with good CRC and you
should accept them


·
The lab code will generate packets with bad CRC and you
should discard them


·
You should generate good CRC for the data you send


The template is avaliable at ~cs460ta/labs/crc_template. Run your code with the lab
version of the code from ~cs460ta/labs/crc on another machine in order to pass off your program for
the TA during his office hours. This
lab code will basically do the same thing as the framework code, but may run
some different tests. It will first received all of the packets you send from
main. When you hit the ENTER key on the server window, it will send you good frames, bit errors in the message, and in the crc.
You may want to run additional tests of your own to make sure that things
are working.


The following passoff levels will apply to this lab:


Passoff Level

Behavior

Points

Minimal Passoff

The data you send has the correct CRC

2 Points

Send and receive

You recognize and accept packets with good CRC

2 Points

Perfect behavior

You recognize and discard bad packets

1 Points