networks-2.rs/network/icmp/src/checksum.rs

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