1mod net;
2
3mod dtls;
4
5use std::{borrow::Cow, collections::BTreeMap, fmt, net::SocketAddr};
6
7use pcap::{Activated, Capture, Savefile};
8
9type State = dtls::State;
10
11#[derive(Clone, Copy)]
12pub struct MsgHeader {
13 src: SocketAddr,
14 dst: SocketAddr,
15 len: u16,
16}
17
18impl fmt::Display for MsgHeader {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 let MsgHeader { src, dst, len } = self;
21 write!(f, "{src} -> {dst} {len}")
22 }
23}
24
25pub fn run<T: Activated + ?Sized>(
26 capture: Capture<T>,
27 file: Option<Savefile>,
28 rng_seed: [u8; 32],
29) -> Result<(), net::DissectError> {
30 let mut connections = BTreeMap::<(SocketAddr, SocketAddr), State>::new();
31
32 let mut buffer = None::<Vec<u8>>;
33 for item in net::UdpIter::new(capture, file) {
34 let (src, dst, data) = item?;
35
36 let _hdr = MsgHeader {
41 src,
42 dst,
43 len: data.len() as _,
44 };
45
46 if data[4..8].eq(b"\x21\x12\xa4\x42") {
48 continue;
49 }
50
51 log::info!("{_hdr}");
52
53 let data = if let Some(mut buffer) = buffer.take() {
54 buffer.extend_from_slice(&data);
55 Cow::Owned(buffer)
56 } else {
57 Cow::Borrowed(data.as_ref())
58 };
59
60 let res = if let Some(cn) = connections.get_mut(&(src, dst)) {
61 cn.handle(&data, true)
62 } else {
63 connections
64 .entry((dst, src))
65 .or_insert_with(|| State::new(rng_seed))
66 .handle(&data, false)
67 };
68
69 if let Err(err) = res {
70 match err {
71 nom::Err::Incomplete(_) => buffer = Some(data.into_owned()),
72 err => log::error!("{err}"),
73 }
74 }
75 }
76
77 Ok(())
78}