From 3d5f47b89f03dc83733648611ea4deb10012cdfa Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 20 Dec 2016 13:16:29 +0000 Subject: [PATCH] Implement TCP representation printing. --- src/wire/ipv4.rs | 2 ++ src/wire/tcp.rs | 62 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/wire/ipv4.rs b/src/wire/ipv4.rs index 6288716..01b93f6 100644 --- a/src/wire/ipv4.rs +++ b/src/wire/ipv4.rs @@ -482,6 +482,8 @@ impl> PrettyPrint for Packet { 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(()) } } diff --git a/src/wire/tcp.rs b/src/wire/tcp.rs index 57caab5..1bff876 100644 --- a/src/wire/tcp.rs +++ b/src/wire/tcp.rs @@ -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, 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> PrettyPrint for Packet { + 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;