1use netscan_pcap::listener::Listner;
2use netscan_pcap::PacketCaptureOptions;
3use netscan_pcap::PacketFrame;
4use std::collections::HashSet;
5use std::net::{IpAddr, Ipv4Addr};
6use std::sync::{Arc, Mutex};
7use std::thread;
8use std::time::Duration;
9use xenet::datalink::DataLinkSender;
10use xenet::net::interface::Interface;
11use xenet::net::mac::MacAddr;
12use xenet::packet::frame::{Frame, ParseOption};
13use xenet::packet::icmp::IcmpType;
14use xenet::packet::icmpv6::Icmpv6Type;
15use xenet::packet::ip::IpNextLevelProtocol;
16use xenet::packet::ipv4::{Ipv4Flags, Ipv4Packet};
17use xenet::packet::ipv6::Ipv6Packet;
18use xenet::packet::tcp::TcpFlags;
19use xenet::packet::udp::UdpPacket;
20use xenet::util::packet_builder::util::PacketBuildOption;
21
22use crate::interface;
23
24use super::result::ProbeResult;
25use super::send;
26use super::setting::LISTENER_WAIT_TIME_MILLIS;
27use super::setting::{ProbeSetting, ProbeTarget, ProbeType};
28
29const DEFAULT_SRC_PORT: u16 = 54433;
30const ICMP_UNUSED_BYTE_SIZE: usize = 4;
31
32pub struct Fingerprinter {
34 pub probe_setting: ProbeSetting,
36 pub probe_result: ProbeResult,
38}
39
40impl Fingerprinter {
41 pub fn new(src_ip: IpAddr) -> Result<Fingerprinter, String> {
43 let network_interface =
44 if let Some(network_interface) = interface::get_interface_by_ip(src_ip) {
45 network_interface
46 } else {
47 return Err(String::from(
48 "Failed to create Scanner. Network Interface not found.",
49 ));
50 };
51 let use_tun = network_interface.is_tun();
52 let loopback = network_interface.is_loopback();
53 let probe_setting: ProbeSetting = ProbeSetting {
54 if_index: network_interface.index,
55 if_name: network_interface.name.clone(),
56 src_mac: if use_tun {
57 MacAddr::zero()
58 } else {
59 interface::get_interface_macaddr(&network_interface)
60 },
61 dst_mac: if use_tun {
62 MacAddr::zero()
63 } else {
64 interface::get_gateway_macaddr(&network_interface)
65 },
66 src_ip: src_ip,
67 src_port: DEFAULT_SRC_PORT,
68 probe_target: ProbeTarget::new(),
69 probe_types: vec![],
70 timeout: Duration::from_millis(30000),
71 wait_time: Duration::from_millis(200),
72 send_rate: Duration::from_millis(1),
73 tunnel: use_tun,
74 loopback: loopback,
75 };
76 let fingerprinter = Fingerprinter {
77 probe_setting: probe_setting,
78 probe_result: ProbeResult::new(IpAddr::V4(Ipv4Addr::LOCALHOST)),
79 };
80 Ok(fingerprinter)
81 }
82 pub fn new_with_index(if_index: u32) -> Result<Fingerprinter, String> {
84 let network_interface =
85 if let Some(network_interface) = interface::get_interface_by_index(if_index) {
86 network_interface
87 } else {
88 return Err(String::from(
89 "Failed to create Scanner. Network Interface not found.",
90 ));
91 };
92 let src_ip: IpAddr = match interface::get_interface_ipv4(&network_interface) {
93 Some(ip) => ip,
94 None => match interface::get_interface_ipv6(&network_interface) {
95 Some(ip) => ip,
96 None => {
97 return Err(String::from(
98 "Failed to create Fingerprinter. Invalid Interface IP address.",
99 ))
100 }
101 },
102 };
103 let use_tun = network_interface.is_tun();
104 let loopback = network_interface.is_loopback();
105 let probe_setting: ProbeSetting = ProbeSetting {
106 if_index: network_interface.index,
107 if_name: network_interface.name.clone(),
108 src_mac: if use_tun {
109 MacAddr::zero()
110 } else {
111 interface::get_interface_macaddr(&network_interface)
112 },
113 dst_mac: if use_tun {
114 MacAddr::zero()
115 } else {
116 interface::get_gateway_macaddr(&network_interface)
117 },
118 src_ip: src_ip,
119 src_port: DEFAULT_SRC_PORT,
120 probe_target: ProbeTarget::new(),
121 probe_types: vec![],
122 timeout: Duration::from_millis(30000),
123 wait_time: Duration::from_millis(200),
124 send_rate: Duration::from_millis(1),
125 tunnel: use_tun,
126 loopback: loopback,
127 };
128 let fingerprinter = Fingerprinter {
129 probe_setting: probe_setting,
130 probe_result: ProbeResult::new(IpAddr::V4(Ipv4Addr::LOCALHOST)),
131 };
132 Ok(fingerprinter)
133 }
134 pub fn new_with_name(if_name: String) -> Result<Fingerprinter, String> {
136 let network_interface =
137 if let Some(network_interface) = interface::get_interface_by_name(if_name) {
138 network_interface
139 } else {
140 return Err(String::from(
141 "Failed to create Scanner. Network Interface not found.",
142 ));
143 };
144 let src_ip = interface::get_interface_ipv4(&network_interface).unwrap_or(
145 interface::get_interface_ipv6(&network_interface)
146 .unwrap_or(IpAddr::V4(std::net::Ipv4Addr::UNSPECIFIED)),
147 );
148 let use_tun = network_interface.is_tun();
149 let loopback = network_interface.is_loopback();
150 let probe_setting: ProbeSetting = ProbeSetting {
151 if_index: network_interface.index,
152 if_name: network_interface.name.clone(),
153 src_mac: if use_tun {
154 MacAddr::zero()
155 } else {
156 interface::get_interface_macaddr(&network_interface)
157 },
158 dst_mac: if use_tun {
159 MacAddr::zero()
160 } else {
161 interface::get_gateway_macaddr(&network_interface)
162 },
163 src_ip: src_ip,
164 src_port: DEFAULT_SRC_PORT,
165 probe_target: ProbeTarget::new(),
166 probe_types: vec![],
167 timeout: Duration::from_millis(30000),
168 wait_time: Duration::from_millis(200),
169 send_rate: Duration::from_millis(1),
170 tunnel: use_tun,
171 loopback: loopback,
172 };
173 let fingerprinter = Fingerprinter {
174 probe_setting: probe_setting,
175 probe_result: ProbeResult::new(IpAddr::V4(Ipv4Addr::LOCALHOST)),
176 };
177 Ok(fingerprinter)
178 }
179 pub fn new_with_gateway_ip(
181 src_ip: IpAddr,
182 gateway_ip: IpAddr,
183 ) -> Result<Fingerprinter, String> {
184 let network_interface =
185 if let Some(network_interface) = interface::get_interface_by_ip(src_ip) {
186 network_interface
187 } else {
188 return Err(String::from(
189 "Failed to create Scanner. Network Interface not found.",
190 ));
191 };
192 let use_tun = network_interface.is_tun();
193 let loopback = network_interface.is_loopback();
194 let dst_mac: MacAddr = match gateway_ip {
195 IpAddr::V4(ip) => get_mac_through_arp(network_interface.clone(), ip),
196 IpAddr::V6(_) => {
197 return Err(String::from(
198 "Failed to create Fingerprinter. Invalid Gateway IP address.",
199 ))
200 }
201 };
202 let probe_setting: ProbeSetting = ProbeSetting {
203 if_index: network_interface.index,
204 if_name: network_interface.name,
205 src_mac: if use_tun {
206 MacAddr::zero()
207 } else {
208 network_interface.mac_addr.unwrap_or(MacAddr::zero())
209 },
210 dst_mac: dst_mac,
211 src_ip: src_ip,
212 src_port: DEFAULT_SRC_PORT,
213 probe_target: ProbeTarget::new(),
214 probe_types: vec![],
215 timeout: Duration::from_millis(30000),
216 wait_time: Duration::from_millis(200),
217 send_rate: Duration::from_millis(1),
218 tunnel: use_tun,
219 loopback: loopback,
220 };
221 let fingerprinter = Fingerprinter {
222 probe_setting: probe_setting,
223 probe_result: ProbeResult::new(IpAddr::V4(Ipv4Addr::LOCALHOST)),
224 };
225 Ok(fingerprinter)
226 }
227 pub fn set_src_port(&mut self, src_port: u16) {
229 self.probe_setting.src_port = src_port;
230 }
231 pub fn set_probe_target(&mut self, probe_target: ProbeTarget) {
233 self.probe_setting.probe_target = probe_target;
234 }
235 pub fn add_probe_type(&mut self, probe_type: ProbeType) {
237 self.probe_setting.probe_types.push(probe_type);
238 }
239 pub fn set_probe_types(&mut self, probe_types: Vec<ProbeType>) {
241 self.probe_setting.probe_types = probe_types;
242 }
243 pub fn set_full_probe(&mut self) {
245 self.probe_setting.probe_types.clear();
246 self.probe_setting
247 .probe_types
248 .push(ProbeType::IcmpEchoProbe);
249 if self.probe_setting.src_ip.is_ipv4() {
250 self.probe_setting
251 .probe_types
252 .push(ProbeType::IcmpTimestampProbe);
253 self.probe_setting
254 .probe_types
255 .push(ProbeType::IcmpAddressMaskProbe);
256 self.probe_setting
257 .probe_types
258 .push(ProbeType::IcmpInformationProbe);
259 }
260 self.probe_setting
261 .probe_types
262 .push(ProbeType::IcmpUnreachableProbe);
263 self.probe_setting
264 .probe_types
265 .push(ProbeType::TcpSynAckProbe);
266 self.probe_setting
267 .probe_types
268 .push(ProbeType::TcpRstAckProbe);
269 self.probe_setting.probe_types.push(ProbeType::TcpEcnProbe);
270 self.probe_setting.probe_types.push(ProbeType::TcpProbe);
271 }
272 pub fn set_timeout(&mut self, timeout: Duration) {
274 self.probe_setting.timeout = timeout;
275 }
276 pub fn set_wait_time(&mut self, wait_time: Duration) {
278 self.probe_setting.wait_time = wait_time;
279 }
280 pub fn set_send_rate(&mut self, send_rate: Duration) {
282 self.probe_setting.send_rate = send_rate;
283 }
284 pub fn get_probe_result(&self) -> ProbeResult {
286 self.probe_result.clone()
287 }
288 pub fn run_probe(&mut self) {
290 let interface: Interface =
291 match crate::interface::get_interface_by_index(self.probe_setting.if_index) {
292 Some(interface) => interface,
293 None => {
294 return;
295 }
296 };
297 let config = xenet::datalink::Config {
298 write_buffer_size: 4096,
299 read_buffer_size: 4096,
300 read_timeout: Some(self.probe_setting.wait_time),
301 write_timeout: None,
302 channel_type: xenet::datalink::ChannelType::Layer2,
303 bpf_fd_attempts: 1000,
304 linux_fanout: None,
305 promiscuous: false,
306 };
307 let (mut tx, mut _rx) = match xenet::datalink::channel(&interface, config) {
308 Ok(xenet::datalink::Channel::Ethernet(tx, rx)) => (tx, rx),
309 Ok(_) => panic!("Unhandled channel type"),
310 Err(e) => panic!("Failed to create channel: {}", e),
311 };
312 let result: ProbeResult = probe(&mut tx, &mut self.probe_setting);
313 self.probe_result = result;
314 }
315 pub fn probe(&mut self) -> ProbeResult {
317 self.run_probe();
318 self.probe_result.clone()
319 }
320}
321
322fn probe(sender: &mut Box<dyn DataLinkSender>, probe_setting: &ProbeSetting) -> ProbeResult {
323 let capture_options: PacketCaptureOptions = PacketCaptureOptions {
324 interface_index: probe_setting.if_index,
325 interface_name: probe_setting.if_name.clone(),
326 src_ips: [probe_setting.probe_target.ip_addr]
327 .iter()
328 .cloned()
329 .collect(),
330 dst_ips: HashSet::new(),
331 src_ports: HashSet::new(),
332 dst_ports: HashSet::new(),
333 ether_types: HashSet::new(),
334 ip_protocols: HashSet::new(),
335 duration: probe_setting.timeout,
336 read_timeout: probe_setting.wait_time,
337 promiscuous: false,
338 store: true,
339 store_limit: u32::MAX,
340 receive_undefined: false,
341 tunnel: probe_setting.tunnel,
342 loopback: probe_setting.loopback,
343 };
344 let listener: Listner = Listner::new(capture_options);
345 let stop_handle = listener.get_stop_handle();
346 let fingerprints: Arc<Mutex<Vec<PacketFrame>>> = Arc::new(Mutex::new(vec![]));
347 let receive_fingerprints: Arc<Mutex<Vec<PacketFrame>>> = Arc::clone(&fingerprints);
348
349 let handler = thread::spawn(move || {
350 let packets: Vec<PacketFrame> = listener.start();
351 for f in packets {
352 match receive_fingerprints.lock() {
353 Ok(mut fingerprints) => {
354 fingerprints.push(f);
355 }
356 Err(e) => {
357 eprintln!("Error: {:?}", e);
358 }
359 }
360 }
361 });
362
363 thread::sleep(Duration::from_millis(LISTENER_WAIT_TIME_MILLIS));
365
366 send::send_packets(sender, &probe_setting);
367 thread::sleep(probe_setting.wait_time);
368
369 match stop_handle.lock() {
371 Ok(mut stop) => {
372 *stop = true;
373 }
374 Err(e) => {
375 eprintln!("Error: {:?}", e);
376 }
377 }
378
379 match handler.join() {
381 Ok(_) => {}
382 Err(e) => {
383 eprintln!("Error: {:?}", e);
384 }
385 }
386 let mut result: ProbeResult = ProbeResult::new_with_types(
388 probe_setting.probe_target.ip_addr,
389 probe_setting.probe_types.clone(),
390 );
391 match fingerprints.lock() {
392 Ok(fingerprints) => {
393 for f in fingerprints.iter() {
394 let ip_next_protocol: IpNextLevelProtocol = if let Some(ip_packet) = &f.ipv4_header
395 {
396 ip_packet.next_level_protocol
397 } else {
398 if let Some(ip_packet) = &f.ipv6_header {
399 ip_packet.next_header
400 } else {
401 continue;
402 }
403 };
404 match ip_next_protocol {
405 IpNextLevelProtocol::Tcp => {
406 if let Some(tcp_fingerprint) = &f.tcp_header {
407 if tcp_fingerprint.flags == TcpFlags::SYN | TcpFlags::ACK
408 && tcp_fingerprint.flags
409 != TcpFlags::SYN | TcpFlags::ACK | TcpFlags::ECE
410 {
411 if let Some(tcp_syn_ack_result) = &mut result.tcp_syn_ack_result {
412 tcp_syn_ack_result.syn_ack_response = true;
413 tcp_syn_ack_result.fingerprints.push(f.clone());
414 }
415 } else if tcp_fingerprint.flags == TcpFlags::RST | TcpFlags::ACK {
416 if let Some(tcp_rst_ack_result) = &mut result.tcp_rst_ack_result {
417 tcp_rst_ack_result.rst_ack_response = true;
418 tcp_rst_ack_result.fingerprints.push(f.clone());
419 }
420 } else if tcp_fingerprint.flags
421 == TcpFlags::SYN | TcpFlags::ACK | TcpFlags::ECE
422 {
423 if let Some(tcp_rst_ack_result) = &mut result.tcp_ecn_result {
424 tcp_rst_ack_result.syn_ack_ece_response = true;
425 tcp_rst_ack_result.fingerprints.push(f.clone());
426 }
427 }
428 }
429 }
430 IpNextLevelProtocol::Udp => {}
431 IpNextLevelProtocol::Icmp => {
432 if let Some(icmp_fingerprint) = &f.icmp_header {
433 match icmp_fingerprint.icmp_type {
434 IcmpType::EchoReply => {
435 if let Some(icmp_echo_result) = &mut result.icmp_echo_result {
436 icmp_echo_result.icmp_echo_reply = true;
437 icmp_echo_result.fingerprints.push(f.clone());
438 }
439 }
440 IcmpType::DestinationUnreachable => {
441 if let Some(icmp_unreachable_ip_result) =
442 &mut result.icmp_unreachable_ip_result
443 {
444 icmp_unreachable_ip_result.icmp_unreachable_reply = true;
445 if let Some(ipv4_packet) = Ipv4Packet::new(
446 &f.payload[ICMP_UNUSED_BYTE_SIZE
447 ..xenet::packet::ipv4::IPV4_HEADER_LEN
448 + ICMP_UNUSED_BYTE_SIZE],
449 ) {
450 if let Some(_udp_packet) = UdpPacket::new(
451 &f.payload[xenet::packet::ipv4::IPV4_HEADER_LEN
452 + ICMP_UNUSED_BYTE_SIZE..],
453 ) {
454 }
456 icmp_unreachable_ip_result.ip_total_length =
457 ipv4_packet.get_total_length();
458 icmp_unreachable_ip_result.ip_id =
459 ipv4_packet.get_identification();
460 if ipv4_packet.get_flags() == Ipv4Flags::DontFragment {
461 icmp_unreachable_ip_result.ip_df = true;
462 }
463 icmp_unreachable_ip_result.ip_ttl =
464 ipv4_packet.get_ttl();
465 }
466 icmp_unreachable_ip_result.icmp_unreachable_size =
467 f.payload.len() - ICMP_UNUSED_BYTE_SIZE;
468 icmp_unreachable_ip_result.fingerprints.push(f.clone());
469 }
470 }
471 IcmpType::TimestampReply => {
472 if let Some(icmp_timestamp_result) =
473 &mut result.icmp_timestamp_result
474 {
475 icmp_timestamp_result.icmp_timestamp_reply = true;
476 icmp_timestamp_result.fingerprints.push(f.clone());
477 }
478 }
479 IcmpType::AddressMaskReply => {
480 if let Some(icmp_address_mask_result) =
481 &mut result.icmp_address_mask_result
482 {
483 icmp_address_mask_result.icmp_address_mask_reply = true;
484 icmp_address_mask_result.fingerprints.push(f.clone());
485 }
486 }
487 IcmpType::InformationReply => {
488 if let Some(icmp_information_result) =
489 &mut result.icmp_information_result
490 {
491 icmp_information_result.icmp_information_reply = true;
492 icmp_information_result.fingerprints.push(f.clone());
493 }
494 }
495 _ => {}
496 }
497 }
498 }
499 IpNextLevelProtocol::Icmpv6 => {
500 if let Some(icmpv6_fingerprint) = &f.icmpv6_header {
501 match icmpv6_fingerprint.icmpv6_type {
502 Icmpv6Type::EchoReply => {
503 if let Some(icmp_echo_result) = &mut result.icmp_echo_result {
504 icmp_echo_result.icmp_echo_reply = true;
505 icmp_echo_result.fingerprints.push(f.clone());
506 }
507 }
508 Icmpv6Type::DestinationUnreachable => {
509 if let Some(icmp_unreachable_ip_result) =
510 &mut result.icmp_unreachable_ip_result
511 {
512 icmp_unreachable_ip_result.icmp_unreachable_reply = true;
513 if let Some(ipv6_packet) = Ipv6Packet::new(
514 &f.payload[ICMP_UNUSED_BYTE_SIZE
515 ..xenet::packet::ipv6::IPV6_HEADER_LEN
516 + ICMP_UNUSED_BYTE_SIZE],
517 ) {
518 if let Some(_udp_packet) = UdpPacket::new(
519 &f.payload[xenet::packet::ipv6::IPV6_HEADER_LEN
520 + ICMP_UNUSED_BYTE_SIZE..],
521 ) {
522 }
524 icmp_unreachable_ip_result.ip_ttl =
525 ipv6_packet.get_hop_limit();
526 }
527 icmp_unreachable_ip_result.icmp_unreachable_size =
528 f.payload.len() - ICMP_UNUSED_BYTE_SIZE;
529 icmp_unreachable_ip_result.ip_total_length =
530 (f.payload.len() - ICMP_UNUSED_BYTE_SIZE) as u16;
531 icmp_unreachable_ip_result.fingerprints.push(f.clone());
532 }
533 }
534 _ => {}
535 }
536 }
537 }
538 _ => {}
539 }
540 }
541 }
542 Err(e) => {
543 eprintln!("Error: {:?}", e);
544 }
545 }
546 return result;
547}
548
549fn get_mac_through_arp(interface: Interface, target_ip: Ipv4Addr) -> MacAddr {
550 let config = xenet::datalink::Config {
552 write_buffer_size: 4096,
553 read_buffer_size: 4096,
554 read_timeout: Some(Duration::from_millis(100)),
555 write_timeout: None,
556 channel_type: xenet::datalink::ChannelType::Layer2,
557 bpf_fd_attempts: 1000,
558 linux_fanout: None,
559 promiscuous: false,
560 };
561 let (mut tx, mut rx) = match xenet::datalink::channel(&interface, config) {
562 Ok(xenet::datalink::Channel::Ethernet(tx, rx)) => (tx, rx),
563 Ok(_) => panic!("Unhandled channel type"),
564 Err(e) => panic!("Failed to create channel: {}", e),
565 };
566 let src_mac = match interface.mac_addr {
567 Some(mac) => mac,
568 None => {
569 return MacAddr::zero();
570 }
571 };
572 let mut packet_option = PacketBuildOption::new();
574 packet_option.src_mac = src_mac;
575 packet_option.dst_mac = MacAddr::zero();
576 packet_option.ether_type = xenet::packet::ethernet::EtherType::Arp;
577 packet_option.src_ip = IpAddr::V4(interface.ipv4[0].addr);
578 packet_option.dst_ip = IpAddr::V4(target_ip);
579
580 let arp_packet: Vec<u8> =
581 xenet::util::packet_builder::util::build_full_arp_packet(packet_option);
582 match tx.send(&arp_packet) {
584 Some(_) => {}
585 None => {}
586 }
587
588 let timeout = Duration::from_millis(10000);
589 let start = std::time::Instant::now();
590 loop {
592 if start.elapsed() > timeout {
593 return MacAddr::zero();
594 }
595 match rx.next() {
596 Ok(packet) => {
597 let frame: Frame = Frame::from_bytes(&packet, ParseOption::default());
598 if let Some(datalink) = frame.datalink {
599 if let Some(ethernet_header) = datalink.ethernet {
600 if ethernet_header.ethertype == xenet::packet::ethernet::EtherType::Arp {
601 if let Some(arp_header) = datalink.arp {
602 if arp_header.sender_hw_addr.address() != src_mac.address()
603 && arp_header.sender_proto_addr == target_ip
604 {
605 return arp_header.sender_hw_addr;
606 }
607 }
608 }
609 }
610 }
611 }
612 Err(_) => {}
613 }
614 }
615}