Skip to content

Commit

Permalink
Respond with ICMP echo request data in echo reply.
Browse files Browse the repository at this point in the history
whitequark committed Dec 13, 2016
1 parent 7e45f2d commit be4ea0a
Showing 5 changed files with 33 additions and 26 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -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
7 changes: 4 additions & 3 deletions src/iface/ethernet.rs
Original file line number Diff line number Diff line change
@@ -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)
}
4 changes: 3 additions & 1 deletion src/wire/ethernet.rs
Original file line number Diff line number Diff line change
@@ -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]
}
24 changes: 13 additions & 11 deletions src/wire/icmpv4.rs
Original file line number Diff line number Diff line change
@@ -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),
22 changes: 12 additions & 10 deletions src/wire/ipv4.rs
Original file line number Diff line number Diff line change
@@ -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),

0 comments on commit be4ea0a

Please sign in to comment.