|  | #![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); | 
|  | } |