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