use bitkit::{bytes, prelude::*};
fn main() -> Result<(), BitError> {
let header: [u8; 20] = [
0x45, 0x00, 0x00, 0x3c,
0x1c, 0x46, 0x40, 0x00,
0x40, 0x06, 0xb1, 0xe6,
0xc0, 0xa8, 0x00, 0x68,
0x08, 0x08, 0x08, 0x08,
];
let b0 = Bits::<u8>::new(header[0]);
let version = b0.extract(4..8)?.get();
let ihl = b0.extract(0..4)?.get();
let total_length = bytes::read_u16_be(&header[2..])?;
let ident = bytes::read_u16_be(&header[4..])?;
let flags_off = Bits::<u16>::new(bytes::read_u16_be(&header[6..])?);
let flags = flags_off.extract(13..16)?.get();
let frag_off = flags_off.extract(0..13)?.get();
let ttl = header[8];
let protocol = header[9];
let checksum = bytes::read_u16_be(&header[10..])?;
let src = bytes::read_u32_be(&header[12..])?;
let dst = bytes::read_u32_be(&header[16..])?;
println!("Version: {}", version);
println!("IHL: {} ({} bytes)", ihl, ihl as usize * 4);
println!("Total length: {}", total_length);
println!("Identification: 0x{:04x}", ident);
println!("Flags: {:03b}", flags);
println!("Frag offset: {}", frag_off);
println!("TTL: {}", ttl);
println!("Protocol: {}", protocol);
println!("Checksum: 0x{:04x}", checksum);
println!("Source: {}", ipv4_str(src));
println!("Destination: {}", ipv4_str(dst));
Ok(())
}
fn ipv4_str(x: u32) -> String {
let b = x.to_be_bytes();
format!("{}.{}.{}.{}", b[0], b[1], b[2], b[3])
}