Fix Ipv4Packet::payload{,_mut}() returning overly long buffers.

These functions only skipped the header, but what they should have
done is cut the packet at its total length and skip the header.
Otherwise, if the buffer the IP packet is constructed from contains
padding, such as Ethernet packets, the payload would be too long.
This commit is contained in:
whitequark 2017-08-30 13:34:50 +00:00
parent 5a066fbc6c
commit d53bdab029
1 changed files with 15 additions and 3 deletions

View File

@ -248,9 +248,9 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Packet<&'a T> {
/// Return a pointer to the payload. /// Return a pointer to the payload.
#[inline] #[inline]
pub fn payload(&self) -> &'a [u8] { pub fn payload(&self) -> &'a [u8] {
let range = self.header_len() as usize; let range = self.header_len() as usize..self.total_len() as usize;
let data = self.buffer.as_ref(); let data = self.buffer.as_ref();
&data[range..] &data[range]
} }
} }
@ -381,7 +381,7 @@ impl<'a, T: AsRef<[u8]> + AsMut<[u8]> + ?Sized> Packet<&'a mut T> {
/// Return a mutable pointer to the payload. /// Return a mutable pointer to the payload.
#[inline] #[inline]
pub fn payload_mut(&mut self) -> &mut [u8] { pub fn payload_mut(&mut self) -> &mut [u8] {
let range = self.header_len() as usize..; let range = self.header_len() as usize..self.total_len() as usize;
let data = self.buffer.as_mut(); let data = self.buffer.as_mut();
&mut data[range] &mut data[range]
} }
@ -611,6 +611,18 @@ mod test {
assert_eq!(&packet.into_inner()[..], &PACKET_BYTES[..]); assert_eq!(&packet.into_inner()[..], &PACKET_BYTES[..]);
} }
#[test]
fn test_overlong() {
let mut bytes = vec![];
bytes.extend(&PACKET_BYTES[..]);
bytes.push(0);
assert_eq!(Packet::new(&bytes).payload().len(),
PAYLOAD_BYTES.len());
assert_eq!(Packet::new(&mut bytes).payload_mut().len(),
PAYLOAD_BYTES.len());
}
static REPR_PACKET_BYTES: [u8; 24] = static REPR_PACKET_BYTES: [u8; 24] =
[0x45, 0x00, 0x00, 0x18, [0x45, 0x00, 0x00, 0x18,
0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00,