xjsc16x - 18 days ago 4x
C Question

# fletcher checksum giving different values

I am trying to use a 16-bit Fletcher checksum here. Basically, my program simulates traffic over the physical layer by "sending" and "receiving" packets between two virtual entities. I am printing out the packets at both sides and they do match, but I am getting a different checksum calculated at the receiving end.

Packet structure:

``````#define  MESSAGE_LENGTH  20
struct   pkt {
int  seqnum;
int  acknum;
int  checksum;
};
``````

This is the code I'm using to compute the checksum of each packet:

``````/*
* Computes the fletcher checksum of the input packet
*/
uint16_t calcChecksum(struct pkt *packet) {
/* the data for the checksum needs to be continuous, so here I am making
a temporary block of memory to hold everything except the packet checksum */
size_t sizeint = sizeof(int);
size_t size = sizeof(struct pkt) - sizeint;
uint8_t *temp = malloc(size);
memcpy(temp, packet, sizeint * 2);   // copy the seqnum and acknum
memcpy(temp + (2*sizeint), &packet->payload, MESSAGE_LENGTH);  // copy data

// calculate checksum
uint16_t checksum = fletcher16((uint8_t const *) &temp, size);
free(temp);
return checksum;
}

/*
* This is a checksum algorithm that I shamelessly copied off a wikipedia page.
*/
uint16_t fletcher16( uint8_t const *data, size_t bytes ) {
uint16_t sum1 = 0xff, sum2 = 0xff;
size_t tlen;

while (bytes) {
tlen = bytes >= 20 ? 20 : bytes;
bytes -= tlen;
do {
sum2 += sum1 += *data++;
} while (--tlen);
sum1 = (sum1 & 0xff) + (sum1 >> 8);
sum2 = (sum2 & 0xff) + (sum2 >> 8);
}
/* Second reduction step to reduce sums to 8 bits */
sum1 = (sum1 & 0xff) + (sum1 >> 8);
sum2 = (sum2 & 0xff) + (sum2 >> 8);
return sum2 << 8 | sum1;
}
``````

I don't know much about checksums and I copied that algorithm off a page I found, so if anyone can understand why the checksums for two otherwise identical packets are different I would greatly appreciate it. Thank you!

The problem occurs because you are not passing the address of `temp` data to the checksum function but rather the address to where the variable `temp` is stored on stack.

You should change

``````uint16_t checksum = fletcher16((uint8_t const *) &temp, size);
``````

to

``````uint16_t checksum = fletcher16((uint8_t const *) temp, size);
^ no & operator
``````
Source (Stackoverflow)