Implement TCP representation printing.

This commit is contained in:
whitequark 2016-12-20 13:16:29 +00:00
parent 513923725e
commit 3d5f47b89f
2 changed files with 62 additions and 2 deletions

View File

@ -482,6 +482,8 @@ impl<T: AsRef<[u8]>> PrettyPrint for Packet<T> {
super::Icmpv4Packet::<&[u8]>::pretty_print(&packet.payload(), f, indent),
ProtocolType::Udp =>
super::UdpPacket::<&[u8]>::pretty_print(&packet.payload(), f, indent),
ProtocolType::Tcp =>
super::TcpPacket::<&[u8]>::pretty_print(&packet.payload(), f, indent),
_ => Ok(())
}
}

View File

@ -1,3 +1,4 @@
use core::fmt;
use byteorder::{ByteOrder, NetworkEndian};
use Error;
@ -389,10 +390,10 @@ impl<'a, T: AsRef<[u8]> + AsMut<[u8]> + ?Sized> Packet<&'a mut T> {
pub struct Repr<'a> {
src_port: u16,
dst_port: u16,
control: Control,
seq_number: u32,
ack_number: Option<u32>,
window_len: u16,
control: Control,
payload: &'a [u8]
}
@ -438,10 +439,10 @@ impl<'a> Repr<'a> {
Ok(Repr {
src_port: packet.src_port(),
dst_port: packet.dst_port(),
control: control,
seq_number: packet.seq_number(),
ack_number: ack_number,
window_len: packet.window_len(),
control: control,
payload: packet.payload()
})
}
@ -474,6 +475,63 @@ impl<'a> Repr<'a> {
}
}
impl<'a, T: AsRef<[u8]> + ?Sized> fmt::Display for Packet<&'a T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Cannot use Repr::parse because we don't have the IP addresses.
try!(write!(f, "TCP src={} dst={}",
self.src_port(), self.dst_port()));
if self.syn() { try!(write!(f, " syn")) }
if self.fin() { try!(write!(f, " fin")) }
if self.rst() { try!(write!(f, " rst")) }
if self.psh() { try!(write!(f, " psh")) }
if self.ece() { try!(write!(f, " ece")) }
if self.cwr() { try!(write!(f, " cwr")) }
if self.ns() { try!(write!(f, " ns" )) }
try!(write!(f, " seq={}", self.seq_number()));
if self.ack() {
try!(write!(f, " ack={}", self.ack_number()));
}
try!(write!(f, " win={}", self.window_len()));
if self.urg() {
try!(write!(f, " urg={}", self.urgent_at()))
}
try!(write!(f, " len={}", self.payload().len()));
Ok(())
}
}
impl<'a> fmt::Display for Repr<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "TCP src={} dst={} ",
self.src_port, self.dst_port));
match self.control {
Control::Syn => try!(write!(f, " syn")),
Control::Fin => try!(write!(f, " fin")),
Control::Rst => try!(write!(f, " rst")),
Control::None => ()
}
try!(write!(f, " seq={}", self.seq_number));
if let Some(ack_number) = self.ack_number {
try!(write!(f, " ack={}", ack_number));
}
try!(write!(f, " win={}", self.window_len));
try!(write!(f, " len={}", self.payload.len()));
Ok(())
}
}
use super::pretty_print::{PrettyPrint, PrettyIndent};
impl<T: AsRef<[u8]>> PrettyPrint for Packet<T> {
fn pretty_print(buffer: &AsRef<[u8]>, f: &mut fmt::Formatter,
indent: &mut PrettyIndent) -> fmt::Result {
match Packet::new(buffer) {
Err(err) => write!(f, "{}({})\n", indent, err),
Ok(packet) => write!(f, "{}{}\n", indent, packet)
}
}
}
#[cfg(test)]
mod test {
use wire::Ipv4Address;