Skip to content

Commit 02c213a

Browse files
committed
disable promiscuous mode by default, fix tests.
By default promiscuous mode is disable and can be enabled with --promiscuous. Fixed the tests, since the order of the flags was backwards, the most relevant flag will be shown first in the prin output. Signed-off-by: Victor Palade <victor@cloudflavor.io>
1 parent cd9296b commit 02c213a

File tree

2 files changed

+65
-51
lines changed

2 files changed

+65
-51
lines changed

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ pub struct SniffOpts {
2828
/// Will try to resolve IP addresses to hostnames
2929
#[structopt(short, long)]
3030
pub resolve: bool,
31+
#[structopt(long)]
32+
promiscuous: bool,
3133
}
3234

3335
#[derive(Debug, StructOpt, Clone)]

src/listener.rs

Lines changed: 63 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,23 @@ use std::fmt::{Display, Formatter};
1111
use std::net::IpAddr;
1212
use std::sync::{Arc, Mutex};
1313
use tokio::signal::unix::{signal, SignalKind};
14-
use tracing::{debug, error, info};
14+
use tracing::{debug, error};
1515

1616
pub async fn run(opts: SniffOpts) -> Result<()> {
1717
let interface = get_interface(&opts.interface)?;
1818

19-
info!("Listening on interface: {}", interface.name);
20-
info!("NO | Source | Destination | Protocol | Flags | Length | Sequence | Window");
19+
println!("Listening on interface: {}\n", interface.name);
20+
println!("NO | Source | Destination | Protocol | Flags | Length | Sequence | Window\n");
21+
println!("--------------------------------------------------------------------------------\n");
2122

2223
// Open a raw socket on the interface
23-
let (_, rx) = match datalink::channel(&interface, Default::default()) {
24+
let (_, rx) = match datalink::channel(
25+
&interface,
26+
datalink::Config {
27+
promiscuous: opts.promiscuous,
28+
..Default::default()
29+
},
30+
) {
2431
Ok(datalink::Channel::Ethernet(tx, rx)) => (tx, rx),
2532
Ok(_) => panic!("unknown channel type"),
2633
Err(e) => panic!("error creating channel: {}", e),
@@ -38,11 +45,14 @@ pub async fn run(opts: SniffOpts) -> Result<()> {
3845
}
3946
_ = tokio::time::sleep(std::time::Duration::from_secs(0)) => {
4047
if let Some(mut packet_info) = handle_receiver(rx_clone){
41-
if matches_filter(packet_info.clone(), &opts) {
48+
// TODO: Find a better solution, if the packet is filtered
49+
// out, it should not be resolved, this adds dns overhead
4250
if opts.resolve {
43-
packet_info.source_ip = resolve_dns(&packet_info.source_ip);
44-
packet_info.destination_ip = resolve_dns(&packet_info.destination_ip);
51+
packet_info.source = resolve_dns(&packet_info.source);
52+
packet_info.destination = resolve_dns(&packet_info.destination);
4553
}
54+
55+
if matches_filter(packet_info.clone(), &opts) {
4656
println!("{}: {}", no, &packet_info);
4757
}
4858
no += 1;
@@ -55,9 +65,9 @@ pub async fn run(opts: SniffOpts) -> Result<()> {
5565

5666
#[derive(Clone, Debug)]
5767
struct PacketInfo {
58-
source_ip: String,
59-
destination_ip: String,
68+
source: String,
6069
source_port: u16,
70+
destination: String,
6171
destination_port: u16,
6272
protocol: IpNextHeaderProtocol,
6373
flags: String,
@@ -74,9 +84,9 @@ impl Display for PacketInfo {
7484
f,
7585
"{} [{}]:{} -> [{}]:{}, {} {} [{} {}] ",
7686
self.protocol.to_string().to_uppercase(),
77-
self.source_ip,
87+
self.source,
7888
self.source_port,
79-
self.destination_ip,
89+
self.destination,
8090
self.destination_port,
8191
self.flags,
8292
self.length,
@@ -88,9 +98,9 @@ impl Display for PacketInfo {
8898
f,
8999
"{} {}:{} -> {}:{} {} {} [{} {}]",
90100
self.protocol.to_string().to_uppercase(),
91-
self.source_ip,
101+
self.source,
92102
self.source_port,
93-
self.destination_ip,
103+
self.destination,
94104
self.destination_port,
95105
self.flags,
96106
self.length,
@@ -115,8 +125,8 @@ fn handle_receiver(rx: Arc<Mutex<Box<dyn DataLinkReceiver>>>) -> Option<PacketIn
115125
debug!("ethernet frame wrapped ipv4 packet: {:?}", ipv4_packet);
116126

117127
return Some(PacketInfo {
118-
source_ip: ipv4_packet.get_source().to_string(),
119-
destination_ip: ipv4_packet.get_destination().to_string(),
128+
source: ipv4_packet.get_source().to_string(),
129+
destination: ipv4_packet.get_destination().to_string(),
120130
source_port: tcp_packet.get_source(),
121131
destination_port: tcp_packet.get_destination(),
122132
protocol: ipv4_packet.get_next_level_protocol(),
@@ -134,8 +144,8 @@ fn handle_receiver(rx: Arc<Mutex<Box<dyn DataLinkReceiver>>>) -> Option<PacketIn
134144
debug!("ethernet frame wrapped ipv6 packet: {:?}", ipv6_packet);
135145

136146
return Some(PacketInfo {
137-
source_ip: ipv6_packet.get_source().to_string(),
138-
destination_ip: ipv6_packet.get_destination().to_string(),
147+
source: ipv6_packet.get_source().to_string(),
148+
destination: ipv6_packet.get_destination().to_string(),
139149
source_port: tcp_packet.get_source(),
140150
destination_port: tcp_packet.get_destination(),
141151
protocol: ipv6_packet.get_next_header(),
@@ -159,8 +169,8 @@ fn handle_receiver(rx: Arc<Mutex<Box<dyn DataLinkReceiver>>>) -> Option<PacketIn
159169
debug!("found unwrapped ipv4 tcp packet: {:?}", ipv4_packet);
160170

161171
return Some(PacketInfo {
162-
source_ip: ipv4_packet.get_source().to_string(),
163-
destination_ip: ipv4_packet.get_destination().to_string(),
172+
source: ipv4_packet.get_source().to_string(),
173+
destination: ipv4_packet.get_destination().to_string(),
164174
source_port: tcp_packet.get_source(),
165175
destination_port: tcp_packet.get_destination(),
166176
protocol: ipv4_packet.get_next_level_protocol(),
@@ -176,8 +186,8 @@ fn handle_receiver(rx: Arc<Mutex<Box<dyn DataLinkReceiver>>>) -> Option<PacketIn
176186

177187
debug!("found unwrapped ipv6 tcp packet: {:?}", ipv6_packet);
178188
return Some(PacketInfo {
179-
source_ip: ipv6_packet.get_source().to_string(),
180-
destination_ip: ipv6_packet.get_destination().to_string(),
189+
source: ipv6_packet.get_source().to_string(),
190+
destination: ipv6_packet.get_destination().to_string(),
181191
source_port: tcp_packet.get_source(),
182192
destination_port: tcp_packet.get_destination(),
183193
protocol: ipv6_packet.get_next_header(),
@@ -199,11 +209,10 @@ fn handle_receiver(rx: Arc<Mutex<Box<dyn DataLinkReceiver>>>) -> Option<PacketIn
199209
}
200210

201211
fn matches_filter(packet_info: PacketInfo, opts: &SniffOpts) -> bool {
202-
if opts.source.is_some() && opts.source.as_ref().unwrap() != &packet_info.source_ip {
212+
if opts.source.is_some() && opts.source.as_ref().unwrap() != &packet_info.source {
203213
return false;
204214
}
205-
if opts.destination.is_some()
206-
&& opts.destination.as_ref().unwrap() != &packet_info.destination_ip
215+
if opts.destination.is_some() && opts.destination.as_ref().unwrap() != &packet_info.destination
207216
{
208217
return false;
209218
}
@@ -246,24 +255,30 @@ fn resolve_dns(ip: &str) -> String {
246255
// perform bitwise operations to determine the flags
247256
fn get_flags(tcp_flags: u16) -> String {
248257
let mut flags = String::new();
249-
if tcp_flags & TcpFlags::SYN > 0 {
250-
flags.push_str("SYN ");
251-
}
252-
if tcp_flags & TcpFlags::ACK > 0 {
253-
flags.push_str("ACK ");
254-
}
255258
if tcp_flags & TcpFlags::FIN > 0 {
256259
flags.push_str("FIN ");
257260
}
261+
if tcp_flags & TcpFlags::SYN > 0 {
262+
flags.push_str("SYN ");
263+
}
258264
if tcp_flags & TcpFlags::RST > 0 {
259265
flags.push_str("RST ");
260266
}
261267
if tcp_flags & TcpFlags::PSH > 0 {
262268
flags.push_str("PSH ");
263269
}
270+
if tcp_flags & TcpFlags::ACK > 0 {
271+
flags.push_str("ACK ");
272+
}
264273
if tcp_flags & TcpFlags::URG > 0 {
265274
flags.push_str("URG ");
266275
}
276+
if tcp_flags & TcpFlags::ECE > 0 {
277+
flags.push_str("ECE ");
278+
}
279+
if tcp_flags & TcpFlags::CWR > 0 {
280+
flags.push_str("CWR ");
281+
}
267282
flags
268283
}
269284

@@ -289,29 +304,26 @@ mod tests {
289304
assert_eq!(get_flags(0b0000000000000000), "");
290305
assert_eq!(get_flags(0b0000000000000001), "FIN ");
291306
assert_eq!(get_flags(0b0000000000000010), "SYN ");
292-
assert_eq!(get_flags(0b0000000000000011), "SYN FIN ");
307+
assert_eq!(get_flags(0b0000000000000011), "FIN SYN ");
293308
assert_eq!(get_flags(0b0000000000000100), "RST ");
294-
assert_eq!(get_flags(0b0000000000000101), "RST FIN ");
295-
assert_eq!(get_flags(0b0000000000000110), "RST SYN ");
296-
assert_eq!(get_flags(0b0000000000000111), "RST SYN FIN ");
309+
assert_eq!(get_flags(0b0000000000000101), "FIN RST ");
310+
assert_eq!(get_flags(0b0000000000000110), "SYN RST ");
311+
assert_eq!(get_flags(0b0000000000000111), "FIN SYN RST ");
297312
assert_eq!(get_flags(0b0000000000001000), "PSH ");
298-
assert_eq!(get_flags(0b0000000000001001), "PSH FIN ");
299-
assert_eq!(get_flags(0b0000000000001010), "PSH SYN ");
300-
assert_eq!(get_flags(0b0000000000001011), "PSH SYN FIN ");
301-
assert_eq!(get_flags(0b0000000000001100), "PSH RST ");
302-
assert_eq!(get_flags(0b0000000000001101), "PSH RST FIN ");
303-
assert_eq!(get_flags(0b0000000000001110), "PSH RST SYN ");
304-
assert_eq!(get_flags(0b0000000000001111), "PSH RST SYN FIN ");
313+
assert_eq!(get_flags(0b0000000000001001), "FIN PSH ");
314+
assert_eq!(get_flags(0b0000000000001010), "SYN PSH ");
315+
assert_eq!(get_flags(0b0000000000001011), "FIN SYN PSH ");
316+
assert_eq!(get_flags(0b0000000000001100), "RST PSH ");
317+
assert_eq!(get_flags(0b0000000000001101), "FIN RST PSH ");
318+
assert_eq!(get_flags(0b0000000000001110), "SYN RST PSH ");
319+
assert_eq!(get_flags(0b0000000000001111), "FIN SYN RST PSH ");
305320
assert_eq!(get_flags(0b0000000000010000), "ACK ");
306-
assert_eq!(get_flags(0b0000000000010001), "ACK FIN ");
307-
assert_eq!(get_flags(0b0000000000010010), "ACK SYN ");
308-
assert_eq!(get_flags(0b0000000000010011), "ACK SYN FIN ");
309-
assert_eq!(get_flags(0b0000000000010100), "ACK RST ");
310-
assert_eq!(get_flags(0b0000000000010101), "ACK RST FIN ");
311-
assert_eq!(get_flags(0b0000000000010110), "ACK RST SYN ");
312-
assert_eq!(get_flags(0b0000000000010111), "ACK RST SYN FIN ");
321+
assert_eq!(get_flags(0b0000000000010001), "FIN ACK ");
322+
assert_eq!(get_flags(0b0000000000010010), "SYN ACK ");
323+
assert_eq!(get_flags(0b0000000000010011), "FIN SYN ACK ");
324+
assert_eq!(get_flags(0b0000000000010100), "RST ACK ");
325+
assert_eq!(get_flags(0b0000000000010101), "FIN RST ACK ");
326+
assert_eq!(get_flags(0b0000000000010110), "SYN RST ACK ");
327+
assert_eq!(get_flags(0b0000000000010111), "FIN SYN RST ACK ");
313328
}
314-
315-
#[test]
316-
fn test_matches_filter() {}
317329
}

0 commit comments

Comments
 (0)