Skip to content

Commit ace1bf5

Browse files
committed
(feat/webrtc-sniffer): use secret key for DTLS
1 parent cde778f commit ace1bf5

File tree

4 files changed

+98
-14
lines changed

4 files changed

+98
-14
lines changed

tools/webrtc-sniffer/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "0.1.0"
44
edition = "2021"
55

66
[dependencies]
7-
clap = { version = "4.5", features = ["derive"] }
7+
clap = { version = "4.5", features = ["derive", "env"] }
88
env_logger = { version = "0.11.6" }
99
log = { version = "0.4.25" }
1010
pcap = { version = "2.2" }
@@ -13,3 +13,5 @@ sudo = { version = "0.6.0" }
1313
hex = { version = "0.4.3" }
1414
etherparse = { version = "0.17.0" }
1515
thiserror = { version = "2.0" }
16+
17+
p2p = { path = "../../p2p" }

tools/webrtc-sniffer/src/bin/sniffer.rs

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ use std::path::PathBuf;
33
use clap::Parser;
44
use pcap::{Capture, ConnectionStatus, Device, IfFlags};
55

6-
// cargo run --release --bin sniffer -- --interface auto --port 443 --path target/test.pcap
6+
use p2p::identity::SecretKey;
7+
8+
// cargo run --release --bin sniffer -- --interface auto --path target/test.pcap
79

810
#[derive(Parser)]
911
struct Cli {
@@ -12,14 +14,26 @@ struct Cli {
1214
help = "name of the interface, use `auto` to determine automatically"
1315
)]
1416
interface: Option<String>,
15-
#[arg(long, help = "filter by the port")]
16-
port: u16,
1717
#[arg(
1818
long,
1919
help = "if `interface` is set, the packets will be written to the `pcap` file, \
2020
otherwise the file will be a source of packets"
2121
)]
2222
path: PathBuf,
23+
24+
/// Peer secret key
25+
#[arg(long, short = 's', env = "OPENMINA_P2P_SEC_KEY")]
26+
pub p2p_secret_key: Option<SecretKey>,
27+
28+
// warning, this overrides `OPENMINA_P2P_SEC_KEY`
29+
/// Compatibility with OCaml Mina node
30+
#[arg(long)]
31+
pub libp2p_keypair: Option<String>,
32+
33+
// warning, this overrides `OPENMINA_P2P_SEC_KEY`
34+
/// Compatibility with OCaml Mina node
35+
#[arg(env = "MINA_LIBP2P_PASS")]
36+
pub libp2p_password: Option<String>,
2337
}
2438

2539
fn init_logger_std() -> Box<dyn log::Log> {
@@ -36,9 +50,30 @@ fn main() {
3650

3751
let Cli {
3852
interface,
39-
port,
4053
path,
54+
p2p_secret_key,
55+
libp2p_keypair,
56+
libp2p_password,
4157
} = Cli::parse();
58+
59+
let secret_key = if let Some(v) = p2p_secret_key {
60+
v
61+
} else {
62+
let (Some(libp2p_keypair), Some(libp2p_password)) = (libp2p_keypair, libp2p_password)
63+
else {
64+
log::error!("no secret key specified");
65+
return;
66+
};
67+
68+
match SecretKey::from_encrypted_file(libp2p_keypair, &libp2p_password) {
69+
Ok(v) => v,
70+
Err(err) => {
71+
log::error!("cannot read secret key {err}");
72+
return;
73+
}
74+
}
75+
};
76+
4277
if let Some(name) = interface {
4378
sudo::escalate_if_needed().unwrap();
4479

@@ -70,13 +105,12 @@ fn main() {
70105
log::info!("will use: {device:?}");
71106
let res = Ok(()).and_then(|()| {
72107
let mut capture = Capture::from_device(device)?.open()?;
73-
let filter = format!("udp port {port}");
74108
capture
75-
.filter(&filter, true)
109+
.filter("udp and not port 443", true)
76110
.expect("Failed to apply filter");
77111
let savefile = capture.savefile(&path)?;
78112

79-
webrtc_sniffer::run(capture, Some(savefile))
113+
webrtc_sniffer::run(capture, Some(savefile), secret_key)
80114
});
81115
if let Err(err) = res {
82116
log::error!("{err}");
@@ -88,7 +122,7 @@ fn main() {
88122
log::info!("use file");
89123
let res = Ok(()).and_then(|()| {
90124
let capture = Capture::from_file(&path)?;
91-
webrtc_sniffer::run(capture, None)
125+
webrtc_sniffer::run(capture, None, secret_key)
92126
});
93127
if let Err(err) = res {
94128
log::error!("{err}");

tools/webrtc-sniffer/src/lib.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
mod net;
22

3+
use p2p::identity::SecretKey;
4+
35
use pcap::{Activated, Capture, Savefile};
46

57
pub fn run<T: Activated + ?Sized>(
68
capture: Capture<T>,
79
file: Option<Savefile>,
10+
secret_key: SecretKey,
811
) -> Result<(), net::DissectError> {
12+
let _ = secret_key;
13+
914
for item in net::UdpIter::new(capture, file) {
1015
let (src, dst, data) = item?;
1116
log::info!(
@@ -17,3 +22,39 @@ pub fn run<T: Activated + ?Sized>(
1722

1823
Ok(())
1924
}
25+
26+
pub fn handle(packet: pcap::Packet) {
27+
use std::net::{IpAddr, SocketAddr};
28+
29+
use etherparse::{NetSlice, SlicedPacket, TransportSlice};
30+
31+
let eth = SlicedPacket::from_ethernet(packet.data).unwrap();
32+
if let (Some(net), Some(transport)) = (eth.net, eth.transport) {
33+
let (src_ip, dst_ip) = match net {
34+
NetSlice::Ipv4(ip) => (
35+
IpAddr::V4(ip.header().source().into()),
36+
IpAddr::V4(ip.header().destination().into()),
37+
),
38+
NetSlice::Ipv6(ip) => (
39+
IpAddr::V6(ip.header().source().into()),
40+
IpAddr::V6(ip.header().destination().into()),
41+
),
42+
NetSlice::Arp(_) => return,
43+
};
44+
let (src_port, dst_port, slice) = match transport {
45+
TransportSlice::Udp(udp) => (udp.source_port(), udp.destination_port(), udp.payload()),
46+
_ => return,
47+
};
48+
49+
let (src, dst, data) = (
50+
SocketAddr::new(src_ip, src_port),
51+
SocketAddr::new(dst_ip, dst_port),
52+
slice,
53+
);
54+
log::info!(
55+
"{src} -> {dst}: {} {}",
56+
data.len(),
57+
hex::encode(&data[..data.len().min(12)])
58+
);
59+
}
60+
}

tools/webrtc-sniffer/src/net.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,18 @@ impl<S: Activated + ?Sized> Iterator for UdpIter<S> {
2828
type Item = Result<(SocketAddr, SocketAddr, Box<[u8]>), DissectError>;
2929

3030
fn next(&mut self) -> Option<Self::Item> {
31-
self.inner
32-
.next()?
33-
.map_err(DissectError::Cap)
34-
.and_then(|x| x)
35-
.transpose()
31+
loop {
32+
match self
33+
.inner
34+
.next()?
35+
.map_err(DissectError::Cap)
36+
.and_then(|x| x)
37+
.transpose()
38+
{
39+
Some(v) => break Some(v),
40+
None => continue,
41+
}
42+
}
3643
}
3744
}
3845

0 commit comments

Comments
 (0)