Does the "C" code algorithm in RFC1071 work well on big-endian machine?

StackOverflow https://stackoverflow.com/questions/14080875

  •  13-12-2021
  •  | 
  •  

문제

As described in RFC1071, an extra 0-byte should be added to the last byte when calculating checksum in the situation of odd count of bytes:

enter image description here

But in the "C" code algorithm, only the last byte is added:

enter image description here

The above code does work on little-endian machine where [Z,0] equals Z, but I think there's some problem on big-endian one where [Z,0] equals Z*256.

So I wonder whether the example "C" code in RFC1071 only works on little-endian machine?

-------------New Added---------------

There's one more example of "breaking the sum into two groups" described in RFC1071:

enter image description here

We can just take the data here (addr[]={0x00, 0x01, 0xf2}) for example:

enter image description here

Here, "standard" represents the situation described in the formula [2], while "C-code" representing the C code algorithm situation.

As we can see, in "standard" situation, the final sum is f201 regardless of endian-difference since there's no endian-issue with the abstract form of [Z,0] after "Swap". But it matters in "C-code" situation because f2 is always the low-byte whether in big-endian or in little-endian.

Thus, the checksum is variable with the same data(addr&count) on different endian.

도움이 되었습니까?

해결책

I think you're right. The code in the RFC adds the last byte in as low-order, regardless of whether it is on a litte-endian or big-endian machine.

In these examples of code on the web we see they have taken special care with the last byte:

https://github.com/sjaeckel/wireshark/blob/master/epan/in_cksum.c

and in

http://www.opensource.apple.com/source/tcpdump/tcpdump-23/tcpdump/print-ip.c

it does this:

if (nleft == 1)
    sum += htons(*(u_char *)w<<8);

Which means that this text in the RFC is incorrect:

Therefore, the sum may be calculated in exactly the same way regardless of the byte order ("big-endian" or "little-endian") of the underlaying hardware. For example, assume a "little- endian" machine summing data that is stored in memory in network ("big-endian") order. Fetching each 16-bit word will swap bytes, resulting in the sum; however, storing the result back into memory will swap the sum back into network byte order.

다른 팁

The following code in place of the original odd byte handling is portable (i.e. will work on both big- and little-endian machines), and doesn't depend on an external function:

if (count > 0)
{
    char buf2[2] = {*addr, 0};
    sum += *(unsigned short *)buf2;
}

(Assumes addr is char * or const char *).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top