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); } }