wirewhale/
packet.rs

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};
7//use std::fmt::Display;
8use 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
72//impl Display for Packet{
73//    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
74//        write!(f, "{:?}\n{}", self.header, self._body)
75//    }
76//}
77//
78//impl Display for PacketBody{
79//    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
80//        write!(f, "{:?} {:?} {}\n{:#?}", self._src, self._dst, self._type_len, self._data)
81//    }
82//}
83
84fn 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}