| #![allow(dead_code)] |
| |
| #[macro_use] |
| extern crate bitfield; |
| |
| use std::net::Ipv4Addr; |
| |
| bitfield!{ |
| struct IpV4Header(MSB0 [u8]); |
| impl Debug; |
| u32; |
| get_version, _: 3, 0; |
| get_ihl, _: 7, 4; |
| get_dscp, _: 13, 8; |
| get_ecn, _: 15, 14; |
| get_total_length, _: 31, 16; |
| get_identification, _: 47, 31; |
| get_df, _: 49; |
| get_mf, _: 50; |
| get_fragment_offset, _: 63, 51; |
| get_time_to_live, _: 71, 64; |
| get_protocol, _: 79, 72; |
| get_header_checksum, _: 95, 79; |
| u8, get_source_address, _: 103, 96, 4; |
| u32, into Ipv4Addr, get_destination_address, _: 159, 128; |
| } |
| |
| impl<T: AsRef<[u8]> + AsMut<[u8]>> IpV4Header<T> { |
| fn get_source_as_ip_addr(&self) -> Ipv4Addr { |
| let mut src = [0; 4]; |
| for (i, src) in src.iter_mut().enumerate() { |
| *src = self.get_source_address(i); |
| } |
| src.into() |
| } |
| } |
| |
| fn main() { |
| let data = [ |
| 0x45, 0x00, 0x00, 0x40, 0x69, 0x27, 0x40, 0x00, 0x40, 0x11, 0x4d, 0x0d, 0xc0, 0xa8, 0x01, |
| 0x2a, 0xc0, 0xa8, 0x01, 0xfe, |
| ]; |
| |
| let header = IpV4Header(data); |
| |
| assert_eq!(header.get_version(), 4); |
| assert_eq!(header.get_total_length(), 64); |
| assert_eq!(header.get_identification(), 0x6927); |
| assert!(header.get_df()); |
| assert!(!header.get_mf()); |
| assert_eq!(header.get_fragment_offset(), 0); |
| assert_eq!(header.get_protocol(), 0x11); |
| println!( |
| "from {} to {}", |
| header.get_source_as_ip_addr(), |
| header.get_destination_address() |
| ); |
| |
| println!("{:#?}", header); |
| } |