Respond with ICMP echo request data in echo reply.

v0.7.x
whitequark 2016-12-13 15:18:56 +00:00
parent 9eb28ed6d7
commit 1c616218a1
5 changed files with 33 additions and 26 deletions

View File

@ -66,7 +66,7 @@ a specific user:
```sh
sudo ip tuntap add name tap0 mode tap user $USER
sudo ip link set tap0 up
sudo ip addr add 192.168.69.100 dev tap0
sudo ip addr add 192.168.69.100/24 dev tap0
```
### smoltcpdump

View File

@ -79,10 +79,11 @@ impl<'a, DeviceT: Device, ArpCacheT: ArpCache> Interface<'a, DeviceT, ArpCacheT>
Arp(ArpRepr),
Icmpv4(Ipv4Repr, Icmpv4Repr<'a>)
}
let mut response = Response::Nop;
let rx_buffer = try!(self.device.receive());
let eth_frame = try!(EthernetFrame::new(rx_buffer));
let eth_frame = try!(EthernetFrame::new(&rx_buffer));
let mut response = Response::Nop;
match eth_frame.ethertype() {
// Snoop all ARP traffic, and respond to ARP packets directed at us.
EthernetProtocolType::Arp => {
@ -144,7 +145,7 @@ impl<'a, DeviceT: Device, ArpCacheT: ArpCache> Interface<'a, DeviceT, ArpCacheT>
let icmp_reply_repr = Icmpv4Repr::EchoReply {
ident: ident,
seq_no: seq_no,
data: &[]
data: data
};
response = Response::Icmpv4(ip_reply_repr, icmp_reply_repr)
}

View File

@ -116,10 +116,12 @@ impl<T: AsRef<[u8]>> Frame<T> {
let raw = NetworkEndian::read_u16(&data[field::ETHERTYPE]);
EtherType::from(raw)
}
}
impl<'a, T: AsRef<[u8]> + ?Sized> Frame<&'a T> {
/// Return a pointer to the payload, without checking for 802.1Q.
#[inline(always)]
pub fn payload(&self) -> &[u8] {
pub fn payload(&self) -> &'a [u8] {
let data = self.buffer.as_ref();
&data[field::PAYLOAD]
}

View File

@ -214,23 +214,25 @@ impl<T: AsRef<[u8]>> Packet<T> {
}
}
/// Return a pointer to the type-specific data.
#[inline(always)]
pub fn data(&self) -> &[u8] {
let data = self.buffer.as_ref();
&data[self.header_len()..]
}
/// Validate the header checksum.
pub fn verify_checksum(&self) -> bool {
let checksum = {
let data = self.buffer.as_ref();
rfc1071_checksum(field::CHECKSUM.start, &data[..self.header_len()])
rfc1071_checksum(field::CHECKSUM.start, data)
};
self.checksum() == checksum
}
}
impl<'a, T: AsRef<[u8]> + ?Sized> Packet<&'a T> {
/// Return a pointer to the type-specific data.
#[inline(always)]
pub fn data(&self) -> &'a [u8] {
let data = self.buffer.as_ref();
&data[self.header_len()..]
}
}
impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
/// Set the message type field.
#[inline(always)]
@ -285,7 +287,7 @@ impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
pub fn fill_checksum(&mut self) {
let checksum = {
let data = self.buffer.as_ref();
rfc1071_checksum(field::CHECKSUM.start, &data[..self.header_len()])
rfc1071_checksum(field::CHECKSUM.start, data)
};
self.set_checksum(checksum)
}
@ -312,7 +314,7 @@ impl<'a> Repr<'a> {
/// Parse an Internet Control Message Protocol version 4 packet and return
/// a high-level representation, or return `Err(())` if the packet is not recognized
/// or is malformed.
pub fn parse<T: AsRef<[u8]>>(packet: &'a Packet<T>) -> Result<Repr<'a>, Error> {
pub fn parse<T: AsRef<[u8]> + ?Sized>(packet: &Packet<&'a T>) -> Result<Repr<'a>, Error> {
match (packet.msg_type(), packet.msg_code()) {
(Type::EchoRequest, 0) => {
Ok(Repr::EchoRequest {
@ -367,7 +369,7 @@ impl<'a> Repr<'a> {
}
}
impl<T: AsRef<[u8]>> fmt::Display for Packet<T> {
impl<'a, T: AsRef<[u8]> + ?Sized> fmt::Display for Packet<&'a T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match Repr::parse(self) {
Ok(repr) => write!(f, "{}", repr),

View File

@ -209,14 +209,6 @@ impl<T: AsRef<[u8]>> Packet<T> {
Address::from_bytes(&data[field::DST_ADDR])
}
/// Return a pointer to the payload.
#[inline(always)]
pub fn payload(&self) -> &[u8] {
let range = self.header_len() as usize;
let data = self.buffer.as_ref();
&data[range..]
}
/// Validate the header checksum.
pub fn verify_checksum(&self) -> bool {
let checksum = {
@ -227,6 +219,16 @@ impl<T: AsRef<[u8]>> Packet<T> {
}
}
impl<'a, T: AsRef<[u8]> + ?Sized> Packet<&'a T> {
/// Return a pointer to the payload.
#[inline(always)]
pub fn payload(&self) -> &'a [u8] {
let range = self.header_len() as usize;
let data = self.buffer.as_ref();
&data[range..]
}
}
impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
/// Set the version field.
#[inline(always)]
@ -359,7 +361,7 @@ pub struct Repr {
impl Repr {
/// Parse an Internet Protocol version 4 packet and return a high-level representation,
/// or return `Err(())` if the packet is not recognized or is malformed.
pub fn parse<T: AsRef<[u8]>>(packet: &Packet<T>) -> Result<Repr, Error> {
pub fn parse<T: AsRef<[u8]> + ?Sized>(packet: &Packet<&T>) -> Result<Repr, Error> {
// Version 4 is expected.
if packet.version() != 4 { return Err(Error::Malformed) }
// Valid checksum is expected.
@ -403,7 +405,7 @@ impl Repr {
}
}
impl<T: AsRef<[u8]>> fmt::Display for Packet<T> {
impl<'a, T: AsRef<[u8]> + ?Sized> fmt::Display for Packet<&'a T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match Repr::parse(self) {
Ok(repr) => write!(f, "{}", repr),