Browse Source

In Repr::emit, do not assume that the packet is pre-zeroed.

whitequark 8 years ago
parent
commit
b2878337e9
2 changed files with 17 additions and 0 deletions
  1. 10 0
      src/wire/ipv4.rs
  2. 7 0
      src/wire/tcp.rs

+ 10 - 0
src/wire/ipv4.rs

@@ -266,6 +266,15 @@ impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
         NetworkEndian::write_u16(&mut data[field::IDENT], value)
     }
 
+    /// Clear the entire flags field.
+    #[inline(always)]
+    pub fn clear_flags(&mut self) {
+        let data = self.buffer.as_mut();
+        let raw = NetworkEndian::read_u16(&data[field::FLG_OFF]);
+        let raw = raw & !0xe000;
+        NetworkEndian::write_u16(&mut data[field::FLG_OFF], raw);
+    }
+
     /// Set the "don't fragment" flag.
     #[inline(always)]
     pub fn set_dont_frag(&mut self, value: bool) {
@@ -398,6 +407,7 @@ impl Repr {
         let total_len = packet.header_len() as u16 + payload_len as u16;
         packet.set_total_len(total_len);
         packet.set_ident(0);
+        packet.clear_flags();
         packet.set_more_frags(false);
         packet.set_dont_frag(true);
         packet.set_frag_offset(0);

+ 7 - 0
src/wire/tcp.rs

@@ -235,6 +235,13 @@ impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
         NetworkEndian::write_u32(&mut data[field::ACK_NUM], value)
     }
 
+    /// Clear the entire flags field.
+    #[inline(always)]
+    pub fn clear_flags(&mut self) {
+        let data = self.buffer.as_mut();
+        NetworkEndian::write_u16(&mut data[field::FLAGS], 0)
+    }
+
     /// Set the FIN flag.
     #[inline(always)]
     pub fn set_fin(&mut self, value: bool) {