executor: fix endianness problem in internet checksum

csum_inet_update does not handle odd number of bytes
on big-endian architectures correctly. When calculating
the checksum of odd number of bytes, the last byte must be
interpreted as LSB on little-endian architectures and
as MSB on big-endian ones in a 16-bit half-word.

Futhermore, the checksum tests assume that the underlying architecture
is always little-endian. When a little-endian machine stores
a calculated checksum into memory, then the checksum's bytes
are automatically swapped. But this is NOT true on a big-endian
architecture.

Signed-off-by: Alexander Egorenkov <Alexander.Egorenkov@ibm.com>
This commit is contained in:
Alexander Egorenkov 2020-06-02 09:25:28 +02:00 committed by Andrey Konovalov
parent 81abc33188
commit c655ec77ca
3 changed files with 20 additions and 20 deletions

View File

@ -372,7 +372,7 @@ static void csum_inet_update(struct csum_inet* csum, const uint8* data, size_t l
csum->acc += *(uint16*)&data[i];
if (length & 1)
csum->acc += (uint16)data[length - 1];
csum->acc += le16toh((uint16)data[length - 1]);
while (csum->acc > 0xffff)
csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16);

View File

@ -41,108 +41,108 @@ static int test_csum_inet()
{// 0
"",
0,
0xffff},
le16toh(0xffff)},
{
// 1
"\x00",
1,
0xffff,
le16toh(0xffff),
},
{
// 2
"\x00\x00",
2,
0xffff,
le16toh(0xffff),
},
{
// 3
"\x00\x00\xff\xff",
4,
0x0000,
le16toh(0x0000),
},
{
// 4
"\xfc",
1,
0xff03,
le16toh(0xff03),
},
{
// 5
"\xfc\x12",
2,
0xed03,
le16toh(0xed03),
},
{
// 6
"\xfc\x12\x3e",
3,
0xecc5,
le16toh(0xecc5),
},
{
// 7
"\xfc\x12\x3e\x00\xc5\xec",
6,
0x0000,
le16toh(0x0000),
},
{
// 8
"\x42\x00\x00\x43\x44\x00\x00\x00\x45\x00\x00\x00\xba\xaa\xbb\xcc\xdd",
17,
0x43e1,
le16toh(0x43e1),
},
{
// 9
"\x42\x00\x00\x43\x44\x00\x00\x00\x45\x00\x00\x00\xba\xaa\xbb\xcc\xdd\x00",
18,
0x43e1,
le16toh(0x43e1),
},
{
// 10
"\x00\x00\x42\x00\x00\x43\x44\x00\x00\x00\x45\x00\x00\x00\xba\xaa\xbb\xcc\xdd",
19,
0x43e1,
le16toh(0x43e1),
},
{
// 11
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\xab\xcd",
15,
0x5032,
le16toh(0x5032),
},
{
// 12
"\x00\x00\x12\x34\x56\x78",
6,
0x5397,
le16toh(0x5397),
},
{
// 13
"\x00\x00\x12\x34\x00\x00\x56\x78\x00\x06\x00\x04\xab\xcd",
14,
0x7beb,
le16toh(0x7beb),
},
{
// 14
"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\xff\xee\xdd\xcc\xbb\xaa\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00\x00\x00\x00\x04\x00\x00\x00\x06\x00\x00\xab\xcd",
44,
0x2854,
le16toh(0x2854),
},
{
// 15
"\x00\x00\x12\x34\x00\x00\x56\x78\x00\x11\x00\x04\xab\xcd",
14,
0x70eb,
le16toh(0x70eb),
},
{
// 16
"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\xff\xee\xdd\xcc\xbb\xaa\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00\x00\x00\x00\x04\x00\x00\x00\x11\x00\x00\xab\xcd",
44,
0x1d54,
le16toh(0x1d54),
},
{
// 17
"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\xff\xee\xdd\xcc\xbb\xaa\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00\x00\x00\x00\x04\x00\x00\x00\x3a\x00\x00\xab\xcd",
44,
0xf453,
le16toh(0xf453),
}};
for (unsigned i = 0; i < ARRAY_SIZE(tests); i++) {

View File

@ -354,7 +354,7 @@ static void csum_inet_update(struct csum_inet* csum, const uint8* data, size_t l
csum->acc += *(uint16*)&data[i];
if (length & 1)
csum->acc += (uint16)data[length - 1];
csum->acc += le16toh((uint16)data[length - 1]);
while (csum->acc > 0xffff)
csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16);