This commit adds a call to `check_len` to all parse methods in the `wire` module. This ensures that no accessor methods are invalid, helping the compiler in optimizing.
@@ -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<T: AsRef<[u8]>>(packet: &Packet<T>) -> Result<Repr> {
+ packet.check_len()?;
+
match (
packet.hardware_type(),
packet.protocol_type(),
@@ -707,6 +707,7 @@ impl<'a> Repr<'a> {
where
T: AsRef<[u8]> + ?Sized,
{
let transaction_id = packet.transaction_id();
let client_hardware_address = packet.client_hardware_address();
let client_ip = packet.client_ip();
@@ -283,6 +283,7 @@ impl Repr {
/// Emit a high-level representation into an Ethernet II frame.
pub fn emit<T: AsRef<[u8]> + AsMut<[u8]>>(&self, frame: &mut Frame<T>) {
+ 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);
@@ -399,6 +399,8 @@ impl<'a> Repr<'a> {
// Valid checksum is expected.
if checksum_caps.icmpv4.rx() && !packet.verify_checksum() {
return Err(Error);
@@ -617,6 +617,8 @@ impl<'a> Repr<'a> {
fn create_packet_from_payload<'a, T>(packet: &Packet<&'a T>) -> Result<(&'a [u8], Ipv6Repr)>
@@ -205,6 +205,8 @@ impl Repr {
// Check if the address is 0.0.0.0 or multicast
let addr = packet.group_addr();
if !addr.is_unspecified() && !addr.is_multicast() {
@@ -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<T: AsRef<[u8]> + ?Sized>(packet: &Packet<&'a T>) -> Result<Repr<'a>> {
Ok(Repr {
next_header: packet.next_header(),
security_parameters_index: packet.security_parameters_index(),
@@ -91,6 +91,7 @@ pub struct Repr {
impl Repr {
/// Parse an IPSec Encapsulating Security Payload packet and return a high-level representation.
sequence_number: packet.sequence_number(),
@@ -633,6 +633,7 @@ impl Repr {
packet: &Packet<&T>,
checksum_caps: &ChecksumCapabilities,
) -> Result<Repr> {
// Version 4 is expected.
if packet.version() != 4 {
@@ -135,6 +135,7 @@ impl<'a> Repr<'a> {
+ header.check_len()?;
Ok(Self {
next_header: header.next_header(),
length: header.header_len(),
@@ -157,6 +157,7 @@ impl Repr {
frag_offset: header.frag_offset(),
more_frags: header.more_frags(),
@@ -70,6 +70,8 @@ impl<'a> Repr<'a> {
let mut options = Vec::new();
let iter = Ipv6OptionsIterator::new(header.options());
@@ -241,6 +241,7 @@ impl<'a> Repr<'a> {
+ opt.check_len()?;
match opt.option_type() {
Type::Pad1 => Ok(Repr::Pad1),
Type::PadN => Ok(Repr::PadN(opt.data_len())),
@@ -376,6 +376,7 @@ impl<'a> Repr<'a> {
match header.routing_type() {
Type::Type2 => Ok(Repr::Type2 {
segments_left: header.segments_left(),
@@ -319,6 +319,7 @@ impl<'a> Repr<'a> {
match packet.msg_type() {
Message::MldQuery => Ok(Repr::Query {
max_resp_code: packet.max_resp_code(),
@@ -230,6 +230,8 @@ impl<'a> Repr<'a> {
let (mut src_ll_addr, mut mtu, mut prefix_info, mut target_ll_addr, mut redirected_hdr) =
(None, None, None, None, None);
@@ -431,6 +431,8 @@ impl<'a> Repr<'a> {
Type::SourceLinkLayerAddr => {
if opt.data_len() >= 1 {
@@ -717,6 +717,8 @@ impl<'p> Repr<'p> {
}
pub fn parse<T: AsRef<[u8]> + ?Sized>(packet: &Packet<&'p T>) -> Result<Self> {
let options = packet.options()?;
match RplControlMessage::from(packet.msg_code()) {
RplControlMessage::DodagInformationSolicitation => {
@@ -234,6 +234,7 @@ impl defmt::Format for Repr {
/// Parse a 6LoWPAN Fragment header.
pub fn parse<T: AsRef<[u8]>>(packet: &Packet<T>) -> Result<Self> {
let size = packet.datagram_size();
let tag = packet.datagram_tag();
@@ -820,6 +820,8 @@ impl<'a> Repr<'a> {
// Source and destination ports must be present.
if packet.src_port() == 0 {
@@ -223,6 +223,8 @@ impl Repr {
// Destination port cannot be omitted (but source port can be).
if packet.dst_port() == 0 {