pcap_async/packet/
mod.rs

1mod container;
2mod future;
3
4pub use container::Container as Packets;
5pub use future::PacketFuture;
6
7use crate::Error;
8
9use byteorder::{ByteOrder, WriteBytesExt};
10use futures::AsyncWriteExt;
11use std::io::Cursor;
12
13#[derive(Clone, Debug)]
14pub struct Packet {
15    pub(crate) timestamp: std::time::SystemTime,
16    pub(crate) actual_length: u32,
17    pub(crate) original_length: u32,
18    pub(crate) data: Vec<u8>,
19}
20
21impl Packet {
22    pub fn into_data(self) -> Vec<u8> {
23        self.data
24    }
25
26    pub fn into_pcap_record<T: ByteOrder>(self) -> Result<Vec<u8>, Error> {
27        self.as_pcap_record::<T>()
28    }
29
30    pub fn as_pcap_record<T: ByteOrder>(&self) -> Result<Vec<u8>, Error> {
31        let data = Vec::with_capacity(self.data.len() + 4 * std::mem::size_of::<u32>());
32        let mut cursor = Cursor::new(data);
33        self.write_pcap_record::<T, Cursor<Vec<u8>>>(&mut cursor)?;
34        Ok(cursor.into_inner())
35    }
36
37    pub fn write_pcap_record<B: ByteOrder, C: WriteBytesExt>(
38        &self,
39        cursor: &mut C,
40    ) -> Result<(), Error> {
41        let dur = self
42            .timestamp
43            .duration_since(std::time::UNIX_EPOCH)
44            .map_err(Error::Time)?;
45
46        cursor
47            .write_u32::<B>(dur.as_secs() as _)
48            .map_err(Error::Io)?;
49        cursor
50            .write_u32::<B>(dur.subsec_micros())
51            .map_err(Error::Io)?;
52        cursor
53            .write_u32::<B>(self.actual_length)
54            .map_err(Error::Io)?;
55        cursor
56            .write_u32::<B>(self.original_length)
57            .map_err(Error::Io)?;
58        cursor.write(self.data.as_slice()).map_err(Error::Io)?;
59        Ok(())
60    }
61
62    pub fn timestamp(&self) -> &std::time::SystemTime {
63        &self.timestamp
64    }
65    pub fn data(&self) -> &[u8] {
66        self.data.as_slice()
67    }
68    pub fn actual_length(&self) -> u32 {
69        self.actual_length
70    }
71    pub fn original_length(&self) -> u32 {
72        self.original_length
73    }
74
75    pub fn new(
76        timestamp: std::time::SystemTime,
77        actual_length: u32,
78        original_length: u32,
79        data: Vec<u8>,
80    ) -> Packet {
81        Packet {
82            timestamp: timestamp,
83            actual_length: actual_length,
84            original_length: original_length,
85            data,
86        }
87    }
88}
89
90#[cfg(test)]
91mod tests {
92    use super::*;
93    use byteorder::ReadBytesExt;
94    use std::io::Read;
95    use std::time::SystemTime;
96
97    #[test]
98    fn converts_to_record() {
99        let ts = SystemTime::now();
100        let packet = Packet {
101            timestamp: ts,
102            actual_length: 100,
103            original_length: 200,
104            data: vec![0u8; 100],
105        };
106        let bytes = packet
107            .as_pcap_record::<byteorder::LittleEndian>()
108            .expect("Failed to convert to record");
109
110        let dur = ts
111            .duration_since(std::time::UNIX_EPOCH)
112            .expect("Could not convert to dur");
113
114        let mut cursor = Cursor::new(bytes);
115        assert_eq!(
116            cursor
117                .read_u32::<byteorder::LittleEndian>()
118                .expect("Failed to read"),
119            dur.as_secs() as u32
120        );
121        assert_eq!(
122            cursor
123                .read_u32::<byteorder::LittleEndian>()
124                .expect("Failed to read"),
125            dur.subsec_micros()
126        );
127        assert_eq!(
128            cursor
129                .read_u32::<byteorder::LittleEndian>()
130                .expect("Failed to read"),
131            100
132        );
133        assert_eq!(
134            cursor
135                .read_u32::<byteorder::LittleEndian>()
136                .expect("Failed to read"),
137            200
138        );
139        let mut read_data = vec![];
140        assert_eq!(
141            cursor.read_to_end(&mut read_data).expect("Failed to read"),
142            100
143        );
144        assert_eq!(read_data, packet.data);
145    }
146}