use nom::number; use nom::IResult; /****************************************************************************** * Struct ******************************************************************************/ /* * User Datagram Header Format * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Source Port | Destination Port | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Length | Checksum | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Data | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct UdpHeader { pub src_port: u16, pub dst_port: u16, pub length: u16, pub checksum: u16, } /****************************************************************************** * Parse ******************************************************************************/ pub fn parse_udp(input: &[u8]) -> IResult<&[u8], UdpHeader> { let (input, src_port) = number::streaming::be_u16(input)?; let (input, dst_port) = number::streaming::be_u16(input)?; let (input, length) = number::streaming::be_u16(input)?; let (input, checksum) = number::streaming::be_u16(input)?; Ok(( input, UdpHeader { src_port, dst_port, length, checksum, }, )) } /****************************************************************************** * TEST ******************************************************************************/ #[cfg(test)] mod tests { use super::parse_udp; use super::UdpHeader; const LAST_SLICE: &'static [u8] = &[0xff]; #[test] fn parse_udp_works() { /* * User Datagram Protocol, Src Port: 9993, Dst Port: 9993 * Source Port: 9993 * Destination Port: 9993 * Length: 145 * Checksum: 0x57d3 [correct] * [Calculated Checksum: 0x57d3] * [Checksum Status: Good] * [Stream index: 3] * [Timestamps] * [Time since first frame: 0.000000000 seconds] * [Time since previous frame: 0.000000000 seconds] * UDP payload (137 bytes) * Data (137 bytes) */ let bytes = [ 0x27, 0x09, /* Source Port */ 0x27, 0x09, /* Destination Port */ 0x00, 0x91, /* Length */ 0x57, 0xd3, /* Checksum */ 0xff, /* Payload */ ]; let expectation = UdpHeader { src_port: 9993, dst_port: 9993, length: 145, checksum: 0x57d3, }; assert_eq!(parse_udp(&bytes), Ok((LAST_SLICE, expectation))); } }