45 lines
1.0 KiB
Rust
45 lines
1.0 KiB
Rust
|
|
pub(crate) struct IPv4ChecksumAccumulator {
|
|
acc: u32,
|
|
}
|
|
|
|
impl IPv4ChecksumAccumulator {
|
|
pub fn new() -> Self {
|
|
return Self { acc: 0 };
|
|
}
|
|
|
|
pub fn add_first_byte(&mut self, b: u8) {
|
|
self.acc += (b as u32) << 8;
|
|
}
|
|
|
|
pub fn add_second_byte(&mut self, b: u8) {
|
|
self.acc += b as u32;
|
|
}
|
|
|
|
pub fn add_last_byte(&mut self, b: u8) {
|
|
self.acc += b as u32;
|
|
}
|
|
|
|
pub fn add_word(&mut self, b: u16) {
|
|
self.acc += b as u32;
|
|
}
|
|
|
|
pub fn add_trailing_data(&mut self, data: &[u8]) {
|
|
for i in (0..(data.len() / 2)).into_iter().map(|i| i * 2) {
|
|
self.add_first_byte(data[i]);
|
|
self.add_second_byte(data[i + 1]);
|
|
}
|
|
if data.len() % 2 != 0 {
|
|
self.add_last_byte(data[data.len() - 1]);
|
|
}
|
|
}
|
|
|
|
pub fn snapshot(&self) -> u16 {
|
|
let mut out = self.acc;
|
|
while out > 0x0000FFFFu32 {
|
|
out = (out & 0x0000FFFFu32) + (out >> 16);
|
|
}
|
|
return !(out as u16);
|
|
}
|
|
}
|