1use crate::l3data::{read_l3data, L3data};
2use anyhow::{Context, Result};
3use async_std::io::ReadExt;
4use byteorder::LittleEndian;
5use byteorder::ReadBytesExt;
6use chrono::{DateTime, Local, TimeZone};
7use crate::filtable::Filtable;
9
10#[derive(Debug, Default, Clone, Copy)]
11struct PacketHeader {
12 _timestamp: DateTime<Local>,
13 _caplen: u32,
14 len: u32,
15}
16
17#[derive(Clone, Copy)]
18struct Macaddr([u8; 6]);
19impl std::fmt::Debug for Macaddr {
20 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21 write!(
22 f,
23 "[{:0>2x}:{:0>2x}:{:0>2x}:{:0>2x}:{:0>2x}:{:0>2x}]",
24 self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5]
25 )
26 }
27}
28#[derive(Debug, Clone, Copy)]
29struct FrameHeader {
30 _src: Macaddr,
31 _dst: Macaddr,
32 _type_len: u16,
33}
34
35#[derive(Debug)]
36struct PacketBody {
37 _header: FrameHeader,
38 _data: Box<dyn L3data>,
39}
40
41#[derive(Debug)]
42pub struct Packet {
43 header: PacketHeader,
44 _body: PacketBody,
45}
46
47impl Packet {
48 pub fn text(&self) -> Vec<String> {
49 let mut ans = vec![
50 format!("{:?}", self.header),
51 format!("{:?}", self._body._header),
52 ];
53 ans.append(self._body._data.text().as_mut());
54 ans
55 }
56 pub fn line(&self) -> String {
57 format!(
58 "{}{:5} {}",
59 self.header._timestamp.format("%H:%M:%S"),
60 self.header.len,
61 self._body._data.line()
62 )
63 }
64}
65
66impl Filtable for Packet {
67 fn is_match(&self, s: &str) -> bool {
68 self.line().contains(s)
69 }
70}
71
72fn read_packet_body(mut bytes: std::collections::VecDeque<u8>) -> Result<PacketBody> {
85 let mut src = [0u8; 6];
86 let mut dst = [0u8; 6];
87 std::io::Read::read_exact(&mut bytes, &mut src).context("read src")?;
88 std::io::Read::read_exact(&mut bytes, &mut dst).context("read dst")?;
89 let type_len = bytes.read_u16::<LittleEndian>().context("read type_len")?;
90 let header = FrameHeader {
91 _src: Macaddr(src),
92 _dst: Macaddr(dst),
93 _type_len: type_len,
94 };
95 let data = read_l3data(bytes, type_len).context("read data")?;
96 let ans = PacketBody {
97 _header: header,
98 _data: data,
99 };
100 Ok(ans)
101}
102
103fn read_packet_header(buf: &[u8]) -> Result<PacketHeader> {
104 let mut slice: &[u8] = buf;
105 let unix_time = slice.read_u32::<LittleEndian>()?;
106 let micro_sec = slice.read_u32::<LittleEndian>()?;
107 let _timestamp = Local
108 .timestamp_opt(unix_time as i64, micro_sec)
109 .earliest()
110 .context("time parse err")?;
111 let _caplen = slice.read_u32::<LittleEndian>()?;
112 let len = slice.read_u32::<LittleEndian>()?;
113 Ok(PacketHeader {
114 _timestamp,
115 _caplen,
116 len,
117 })
118}
119
120pub async fn read_packet(read: &mut (impl ReadExt + Unpin)) -> Result<Packet> {
121 let header_buf_len = 16;
122 let mut header_buf = Vec::with_capacity(header_buf_len);
123 read.take(header_buf_len as u64)
124 .read_to_end(&mut header_buf)
125 .await?;
126 let header = read_packet_header(header_buf.as_slice())?;
127 let mut body_buf = Vec::with_capacity(header.len.try_into()?);
128 read.take(header.len.try_into()?)
129 .read_to_end(&mut body_buf)
130 .await?;
131 let body = read_packet_body(body_buf.into())?;
132 Ok(Packet {
133 header,
134 _body: body,
135 })
136}