diff --git a/src/wire/arp.rs b/src/wire/arp.rs index bb0df3a0e..c7d0b8add 100644 --- a/src/wire/arp.rs +++ b/src/wire/arp.rs @@ -271,6 +271,8 @@ impl Repr { /// Parse an Address Resolution Protocol packet and return a high-level representation, /// or return `Err(Error)` if the packet is not recognized. pub fn parse>(packet: &Packet) -> Result { + packet.check_len()?; + match ( packet.hardware_type(), packet.protocol_type(), diff --git a/src/wire/dhcpv4.rs b/src/wire/dhcpv4.rs index cae912945..b00f26ff7 100644 --- a/src/wire/dhcpv4.rs +++ b/src/wire/dhcpv4.rs @@ -707,6 +707,7 @@ impl<'a> Repr<'a> { where T: AsRef<[u8]> + ?Sized, { + packet.check_len()?; let transaction_id = packet.transaction_id(); let client_hardware_address = packet.client_hardware_address(); let client_ip = packet.client_ip(); diff --git a/src/wire/ethernet.rs b/src/wire/ethernet.rs index 53dc1eacb..110e3d37b 100644 --- a/src/wire/ethernet.rs +++ b/src/wire/ethernet.rs @@ -283,6 +283,7 @@ impl Repr { /// Emit a high-level representation into an Ethernet II frame. pub fn emit + AsMut<[u8]>>(&self, frame: &mut Frame) { + assert!(frame.buffer.as_ref().len() >= self.buffer_len()); frame.set_src_addr(self.src_addr); frame.set_dst_addr(self.dst_addr); frame.set_ethertype(self.ethertype); diff --git a/src/wire/icmpv4.rs b/src/wire/icmpv4.rs index 60e12153f..0ef752511 100644 --- a/src/wire/icmpv4.rs +++ b/src/wire/icmpv4.rs @@ -399,6 +399,8 @@ impl<'a> Repr<'a> { where T: AsRef<[u8]> + ?Sized, { + packet.check_len()?; + // Valid checksum is expected. if checksum_caps.icmpv4.rx() && !packet.verify_checksum() { return Err(Error); diff --git a/src/wire/icmpv6.rs b/src/wire/icmpv6.rs index 72d2451d8..3d68b2a11 100644 --- a/src/wire/icmpv6.rs +++ b/src/wire/icmpv6.rs @@ -617,6 +617,8 @@ impl<'a> Repr<'a> { where T: AsRef<[u8]> + ?Sized, { + packet.check_len()?; + fn create_packet_from_payload<'a, T>(packet: &Packet<&'a T>) -> Result<(&'a [u8], Ipv6Repr)> where T: AsRef<[u8]> + ?Sized, diff --git a/src/wire/igmp.rs b/src/wire/igmp.rs index ac13ece1a..ac1f48d2d 100644 --- a/src/wire/igmp.rs +++ b/src/wire/igmp.rs @@ -205,6 +205,8 @@ impl Repr { where T: AsRef<[u8]> + ?Sized, { + packet.check_len()?; + // Check if the address is 0.0.0.0 or multicast let addr = packet.group_addr(); if !addr.is_unspecified() && !addr.is_multicast() { diff --git a/src/wire/ipsec_ah.rs b/src/wire/ipsec_ah.rs index 1c3f00b1d..326f76e24 100644 --- a/src/wire/ipsec_ah.rs +++ b/src/wire/ipsec_ah.rs @@ -174,6 +174,7 @@ pub struct Repr<'a> { impl<'a> Repr<'a> { /// Parse an IPSec Authentication Header packet and return a high-level representation. pub fn parse + ?Sized>(packet: &Packet<&'a T>) -> Result> { + packet.check_len()?; Ok(Repr { next_header: packet.next_header(), security_parameters_index: packet.security_parameters_index(), diff --git a/src/wire/ipsec_esp.rs b/src/wire/ipsec_esp.rs index d0cd5721c..7a359613d 100644 --- a/src/wire/ipsec_esp.rs +++ b/src/wire/ipsec_esp.rs @@ -91,6 +91,7 @@ pub struct Repr { impl Repr { /// Parse an IPSec Encapsulating Security Payload packet and return a high-level representation. pub fn parse>(packet: &Packet) -> Result { + packet.check_len()?; Ok(Repr { security_parameters_index: packet.security_parameters_index(), sequence_number: packet.sequence_number(), diff --git a/src/wire/ipv4.rs b/src/wire/ipv4.rs index 1027fc262..2efd2b1eb 100644 --- a/src/wire/ipv4.rs +++ b/src/wire/ipv4.rs @@ -633,6 +633,7 @@ impl Repr { packet: &Packet<&T>, checksum_caps: &ChecksumCapabilities, ) -> Result { + packet.check_len()?; // Version 4 is expected. if packet.version() != 4 { return Err(Error); diff --git a/src/wire/ipv6ext_header.rs b/src/wire/ipv6ext_header.rs index bc8ef879f..ded4a1886 100644 --- a/src/wire/ipv6ext_header.rs +++ b/src/wire/ipv6ext_header.rs @@ -135,6 +135,7 @@ impl<'a> Repr<'a> { where T: AsRef<[u8]> + ?Sized, { + header.check_len()?; Ok(Self { next_header: header.next_header(), length: header.header_len(), diff --git a/src/wire/ipv6fragment.rs b/src/wire/ipv6fragment.rs index cf6b6d0ce..ce28bc1b9 100644 --- a/src/wire/ipv6fragment.rs +++ b/src/wire/ipv6fragment.rs @@ -157,6 +157,7 @@ impl Repr { where T: AsRef<[u8]> + ?Sized, { + header.check_len()?; Ok(Repr { frag_offset: header.frag_offset(), more_frags: header.more_frags(), diff --git a/src/wire/ipv6hbh.rs b/src/wire/ipv6hbh.rs index bc6830036..9fa33a3af 100644 --- a/src/wire/ipv6hbh.rs +++ b/src/wire/ipv6hbh.rs @@ -70,6 +70,8 @@ impl<'a> Repr<'a> { where T: AsRef<[u8]> + ?Sized, { + header.check_len()?; + let mut options = Vec::new(); let iter = Ipv6OptionsIterator::new(header.options()); diff --git a/src/wire/ipv6option.rs b/src/wire/ipv6option.rs index dfbd6acad..21024ae9c 100644 --- a/src/wire/ipv6option.rs +++ b/src/wire/ipv6option.rs @@ -241,6 +241,7 @@ impl<'a> Repr<'a> { where T: AsRef<[u8]> + ?Sized, { + opt.check_len()?; match opt.option_type() { Type::Pad1 => Ok(Repr::Pad1), Type::PadN => Ok(Repr::PadN(opt.data_len())), diff --git a/src/wire/ipv6routing.rs b/src/wire/ipv6routing.rs index 14a1c5ecd..a2b91e9ce 100644 --- a/src/wire/ipv6routing.rs +++ b/src/wire/ipv6routing.rs @@ -376,6 +376,7 @@ impl<'a> Repr<'a> { where T: AsRef<[u8]> + ?Sized, { + header.check_len()?; match header.routing_type() { Type::Type2 => Ok(Repr::Type2 { segments_left: header.segments_left(), diff --git a/src/wire/mld.rs b/src/wire/mld.rs index 18872b502..c33415151 100644 --- a/src/wire/mld.rs +++ b/src/wire/mld.rs @@ -319,6 +319,7 @@ impl<'a> Repr<'a> { where T: AsRef<[u8]> + ?Sized, { + packet.check_len()?; match packet.msg_type() { Message::MldQuery => Ok(Repr::Query { max_resp_code: packet.max_resp_code(), diff --git a/src/wire/ndisc.rs b/src/wire/ndisc.rs index 691b69b5e..99663159e 100644 --- a/src/wire/ndisc.rs +++ b/src/wire/ndisc.rs @@ -230,6 +230,8 @@ impl<'a> Repr<'a> { where T: AsRef<[u8]> + ?Sized, { + packet.check_len()?; + let (mut src_ll_addr, mut mtu, mut prefix_info, mut target_ll_addr, mut redirected_hdr) = (None, None, None, None, None); diff --git a/src/wire/ndiscoption.rs b/src/wire/ndiscoption.rs index eff7a93c1..0236d4351 100644 --- a/src/wire/ndiscoption.rs +++ b/src/wire/ndiscoption.rs @@ -431,6 +431,8 @@ impl<'a> Repr<'a> { where T: AsRef<[u8]> + ?Sized, { + opt.check_len()?; + match opt.option_type() { Type::SourceLinkLayerAddr => { if opt.data_len() >= 1 { diff --git a/src/wire/rpl.rs b/src/wire/rpl.rs index 0a8467cae..a67c85e11 100644 --- a/src/wire/rpl.rs +++ b/src/wire/rpl.rs @@ -717,6 +717,8 @@ impl<'p> Repr<'p> { } pub fn parse + ?Sized>(packet: &Packet<&'p T>) -> Result { + packet.check_len()?; + let options = packet.options()?; match RplControlMessage::from(packet.msg_code()) { RplControlMessage::DodagInformationSolicitation => { diff --git a/src/wire/sixlowpan/frag.rs b/src/wire/sixlowpan/frag.rs index de4570289..eed7f051f 100644 --- a/src/wire/sixlowpan/frag.rs +++ b/src/wire/sixlowpan/frag.rs @@ -234,6 +234,7 @@ impl defmt::Format for Repr { impl Repr { /// Parse a 6LoWPAN Fragment header. pub fn parse>(packet: &Packet) -> Result { + packet.check_len()?; let size = packet.datagram_size(); let tag = packet.datagram_tag(); diff --git a/src/wire/tcp.rs b/src/wire/tcp.rs index 24821430a..a6612d124 100644 --- a/src/wire/tcp.rs +++ b/src/wire/tcp.rs @@ -820,6 +820,8 @@ impl<'a> Repr<'a> { where T: AsRef<[u8]> + ?Sized, { + packet.check_len()?; + // Source and destination ports must be present. if packet.src_port() == 0 { return Err(Error); diff --git a/src/wire/udp.rs b/src/wire/udp.rs index 77f9f84b3..bea54af93 100644 --- a/src/wire/udp.rs +++ b/src/wire/udp.rs @@ -223,6 +223,8 @@ impl Repr { where T: AsRef<[u8]> + ?Sized, { + packet.check_len()?; + // Destination port cannot be omitted (but source port can be). if packet.dst_port() == 0 { return Err(Error);