Respond with ICMP echo request data in echo reply.
parent
9eb28ed6d7
commit
1c616218a1
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Reference in New Issue