net: fix IP checksum overflow during reduction
When reducing the checksum from a 32-bit or 64-bit intermediate, we can get an overflow after the first overflow handling step: 0000_8000_8000_ffff -> 10_ffff -> 1_000f -> 0010 Since we lacked the second step, we got an off-by-one in the checksum.
This commit is contained in:
@@ -41,7 +41,8 @@ uint16_t ip_checksum(const void* data, size_t len) {
|
||||
len -= 1;
|
||||
}
|
||||
csum = (csum & 0xffff) + ((csum >> 16) & 0xffff) + ((csum >> 32) & 0xffff) + (csum >> 48);
|
||||
csum += csum >> 16;
|
||||
csum = (csum & 0xffff) + (csum >> 16);
|
||||
csum = (csum & 0xffff) + (csum >> 16);
|
||||
return htons(~csum);
|
||||
}
|
||||
|
||||
@@ -144,7 +145,8 @@ void checksummer::sum(const packet& p) {
|
||||
}
|
||||
|
||||
uint16_t checksummer::get() const {
|
||||
return partial + (partial >> 16);
|
||||
auto tmp = (partial & 0xffff) + (partial >> 16);
|
||||
return tmp + (tmp >> 16);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user