Browse Source

Rework the pretty printer to avoid superfluous trailing newlines.

whitequark 7 years ago
parent
commit
b1680368fe
9 changed files with 54 additions and 43 deletions
  1. 1 2
      examples/utils.rs
  2. 2 2
      src/wire/arp.rs
  3. 10 7
      src/wire/ethernet.rs
  4. 6 5
      src/wire/icmpv4.rs
  5. 4 3
      src/wire/ip.rs
  6. 23 18
      src/wire/ipv4.rs
  7. 4 2
      src/wire/pretty_print.rs
  8. 2 2
      src/wire/tcp.rs
  9. 2 2
      src/wire/udp.rs

+ 1 - 2
examples/utils.rs

@@ -23,8 +23,7 @@ pub fn setup_logging_with_clock<F>(filter: &str, since_startup: F)
                 format!("\x1b[0m{} ({}): {}\x1b[0m", timestamp,
                         record.target().replace("smoltcp::", ""), record.args())
             } else if record.level() == LogLevel::Trace {
-                let mut message = format!("{}", record.args());
-                message.pop();
+                let message = format!("{}", record.args());
                 format!("\x1b[37m{} {}\x1b[0m", timestamp,
                         message.replace("\n", "\n             "))
             } else {

+ 2 - 2
src/wire/arp.rs

@@ -356,8 +356,8 @@ 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_checked(buffer) {
-            Err(err)  => write!(f, "{}({})\n", indent, err),
-            Ok(frame) => write!(f, "{}{}\n", indent, frame)
+            Err(err) => write!(f, "{}({})", indent, err),
+            Ok(packet) => write!(f, "{}{}", indent, packet)
         }
     }
 }

+ 10 - 7
src/wire/ethernet.rs

@@ -211,17 +211,20 @@ impl<T: AsRef<[u8]>> PrettyPrint for Frame<T> {
     fn pretty_print(buffer: &AsRef<[u8]>, f: &mut fmt::Formatter,
                     indent: &mut PrettyIndent) -> fmt::Result {
         let frame = match Frame::new_checked(buffer) {
-            Err(err)  => return write!(f, "{}({})\n", indent, err),
+            Err(err)  => return write!(f, "{}({})", indent, err),
             Ok(frame) => frame
         };
-        write!(f, "{}{}\n", indent, frame)?;
-        indent.increase();
+        write!(f, "{}{}", indent, frame)?;
 
         match frame.ethertype() {
-            EtherType::Arp =>
-                super::ArpPacket::<&[u8]>::pretty_print(&frame.payload(), f, indent),
-            EtherType::Ipv4 =>
-                super::Ipv4Packet::<&[u8]>::pretty_print(&frame.payload(), f, indent),
+            EtherType::Arp => {
+                indent.increase(f)?;
+                super::ArpPacket::<&[u8]>::pretty_print(&frame.payload(), f, indent)
+            }
+            EtherType::Ipv4 => {
+                indent.increase(f)?;
+                super::Ipv4Packet::<&[u8]>::pretty_print(&frame.payload(), f, indent)
+            }
             _ => Ok(())
         }
     }

+ 6 - 5
src/wire/icmpv4.rs

@@ -532,15 +532,16 @@ impl<T: AsRef<[u8]>> PrettyPrint for Packet<T> {
     fn pretty_print(buffer: &AsRef<[u8]>, f: &mut fmt::Formatter,
                     indent: &mut PrettyIndent) -> fmt::Result {
         let packet = match Packet::new_checked(buffer) {
-            Err(err)   => return write!(f, "{}({})\n", indent, err),
+            Err(err)   => return write!(f, "{}({})", indent, err),
             Ok(packet) => packet
         };
-        write!(f, "{}{}\n", indent, packet)?;
+        write!(f, "{}{}", indent, packet)?;
 
-        indent.increase();
         match packet.msg_type() {
-            Message::DstUnreachable =>
-                super::Ipv4Packet::<&[u8]>::pretty_print(&packet.data(), f, indent),
+            Message::DstUnreachable => {
+                indent.increase(f)?;
+                super::Ipv4Packet::<&[u8]>::pretty_print(&packet.data(), f, indent)
+            }
             _ => Ok(())
         }
     }

+ 4 - 3
src/wire/ip.rs

@@ -595,11 +595,12 @@ pub mod checksum {
     }
 
     // We use this in pretty printer implementations.
-    pub(crate) fn write_checksum(f: &mut fmt::Formatter, correct: bool) -> fmt::Result {
+    pub(crate) fn format_checksum(f: &mut fmt::Formatter, correct: bool) -> fmt::Result {
         if !correct {
-            write!(f, " (checksum incorrect)")?;
+            write!(f, " (checksum incorrect)")
+        } else {
+            Ok(())
         }
-        write!(f, "\n")
     }
 }
 

+ 23 - 18
src/wire/ipv4.rs

@@ -567,17 +567,19 @@ 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 {
-        use wire::ip::checksum::write_checksum;
+        use wire::ip::checksum::format_checksum;
+        use wire::{Icmpv4Packet, TcpPacket, TcpRepr, UdpPacket, UdpRepr};
+
         let checksum_caps = ChecksumCapabilities::ignored();
 
         let (ip_repr, payload) = match Packet::new_checked(buffer) {
-            Err(err) => return write!(f, "{}({})\n", indent, err),
+            Err(err) => return write!(f, "{}({})", indent, err),
             Ok(ip_packet) => {
                 match Repr::parse(&ip_packet, &checksum_caps) {
                     Err(_) => return Ok(()),
                     Ok(ip_repr) => {
                         write!(f, "{}{}", indent, ip_repr)?;
-                        write_checksum(f, ip_packet.verify_checksum())?;
+                        format_checksum(f, ip_packet.verify_checksum())?;
                         (ip_repr, ip_packet.payload())
                     }
                 }
@@ -587,35 +589,38 @@ impl<T: AsRef<[u8]>> PrettyPrint for Packet<T> {
         let src_addr = ip_repr.src_addr.into();
         let dst_addr = ip_repr.dst_addr.into();
 
-        indent.increase();
         match ip_repr.protocol {
-            Protocol::Icmp =>
-                super::Icmpv4Packet::<&[u8]>::pretty_print(&payload, f, indent),
+            Protocol::Icmp => {
+                indent.increase(f)?;
+                Icmpv4Packet::<&[u8]>::pretty_print(&payload.as_ref(), f, indent)
+            }
             Protocol::Udp => {
-                match super::UdpPacket::new_checked(payload) {
-                    Err(err) => write!(f, "{}({})\n", indent, err),
+                indent.increase(f)?;
+                match UdpPacket::<&[u8]>::new_checked(payload.as_ref()) {
+                    Err(err) => write!(f, "{}({})", indent, err),
                     Ok(udp_packet) => {
-                        match super::UdpRepr::parse(&udp_packet, &src_addr, &dst_addr,
-                                                    &checksum_caps) {
-                            Err(err) => write!(f, "{}{} ({})\n", indent, udp_packet, err),
+                        match UdpRepr::parse(&udp_packet, &src_addr, &dst_addr, &checksum_caps) {
+                            Err(err) => write!(f, "{}{} ({})", indent, udp_packet, err),
                             Ok(udp_repr) => {
                                 write!(f, "{}{}", indent, udp_repr)?;
-                                write_checksum(f, udp_packet.verify_checksum(&src_addr, &dst_addr))
+                                let valid = udp_packet.verify_checksum(&src_addr, &dst_addr);
+                                format_checksum(f, valid)
                             }
                         }
                     }
                 }
             }
             Protocol::Tcp => {
-                match super::TcpPacket::new_checked(payload) {
-                    Err(err) => write!(f, "{}({})\n", indent, err),
+                indent.increase(f)?;
+                match TcpPacket::<&[u8]>::new_checked(payload.as_ref()) {
+                    Err(err) => write!(f, "{}({})", indent, err),
                     Ok(tcp_packet) => {
-                        match super::TcpRepr::parse(&tcp_packet, &src_addr, &dst_addr,
-                                                    &checksum_caps) {
-                            Err(err) => write!(f, "{}{} ({})\n", indent, tcp_packet, err),
+                        match TcpRepr::parse(&tcp_packet, &src_addr, &dst_addr, &checksum_caps) {
+                            Err(err) => write!(f, "{}{} ({})", indent, tcp_packet, err),
                             Ok(tcp_repr) => {
                                 write!(f, "{}{}", indent, tcp_repr)?;
-                                write_checksum(f, tcp_packet.verify_checksum(&src_addr, &dst_addr))
+                                let valid = tcp_packet.verify_checksum(&src_addr, &dst_addr);
+                                format_checksum(f, valid)
                             }
                         }
                     }

+ 4 - 2
src/wire/pretty_print.rs

@@ -48,8 +48,10 @@ impl PrettyIndent {
     }
 
     /// Increase indentation level.
-    pub fn increase(&mut self) {
-        self.level += 1
+    pub fn increase(&mut self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "\n")?;
+        self.level += 1;
+        Ok(())
     }
 }
 

+ 2 - 2
src/wire/tcp.rs

@@ -842,8 +842,8 @@ 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_checked(buffer) {
-            Err(err)   => write!(f, "{}({})\n", indent, err),
-            Ok(packet) => write!(f, "{}{}\n", indent, packet)
+            Err(err)   => write!(f, "{}({})", indent, err),
+            Ok(packet) => write!(f, "{}{}", indent, packet)
         }
     }
 }

+ 2 - 2
src/wire/udp.rs

@@ -274,8 +274,8 @@ 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_checked(buffer) {
-            Err(err)   => write!(f, "{}({})\n", indent, err),
-            Ok(packet) => write!(f, "{}{}\n", indent, packet)
+            Err(err)   => write!(f, "{}({})", indent, err),
+            Ok(packet) => write!(f, "{}{}", indent, packet)
         }
     }
 }