Skip to main content

pistol/
layer.rs

1use pcapture::pcapng::EnhancedPacketBlock;
2use pcapture::pcapng::GeneralBlock;
3use pnet::datalink;
4use pnet::datalink::Channel::Ethernet;
5use pnet::datalink::ChannelType;
6use pnet::datalink::Config;
7use pnet::datalink::MacAddr;
8use pnet::datalink::NetworkInterface;
9use pnet::datalink::interfaces;
10use pnet::packet::Packet;
11use pnet::packet::arp::ArpPacket;
12use pnet::packet::ethernet::EtherType;
13use pnet::packet::ethernet::EtherTypes;
14use pnet::packet::ethernet::EthernetPacket;
15use pnet::packet::ethernet::MutableEthernetPacket;
16use pnet::packet::icmp::IcmpCode;
17use pnet::packet::icmp::IcmpPacket;
18use pnet::packet::icmp::IcmpType;
19use pnet::packet::icmpv6::Icmpv6Code;
20use pnet::packet::icmpv6::Icmpv6Packet;
21use pnet::packet::icmpv6::Icmpv6Type;
22use pnet::packet::ip::IpNextHeaderProtocols;
23use pnet::packet::ipv4::Ipv4Packet;
24use pnet::packet::ipv6::Ipv6Packet;
25use pnet::packet::tcp::TcpPacket;
26use pnet::packet::udp::UdpPacket;
27use std::net::IpAddr;
28use std::net::Ipv4Addr;
29use std::net::Ipv6Addr;
30use std::panic::Location;
31use std::sync::mpsc::Receiver;
32use std::sync::mpsc::channel;
33use std::time::Duration;
34use std::time::Instant;
35use tracing::debug;
36use tracing::error;
37use tracing::warn;
38use uuid::Uuid;
39
40use crate::DEFAULT_TIMEOUT;
41use crate::PISTOL_PCAPNG;
42use crate::PISTOL_PCAPNG_FLAG;
43use crate::PISTOL_RUNNER_IS_RUNNING;
44use crate::PistolChannel;
45use crate::UNIFIED_RECV_MATCHS;
46use crate::error::PistolError;
47use crate::route::RouteVia;
48use crate::route::get_default_route;
49use crate::route::search_route_table;
50
51pub const ETHERNET_HEADER_SIZE: usize = 14;
52pub const ARP_HEADER_SIZE: usize = 28;
53pub const IPV4_HEADER_SIZE: usize = 20;
54pub const IPV6_HEADER_SIZE: usize = 40;
55pub const TCP_HEADER_SIZE: usize = 20;
56pub const UDP_HEADER_SIZE: usize = 8;
57pub const ICMP_HEADER_SIZE: usize = 8;
58// big enough to store all data
59pub const ETHERNET_BUFF_SIZE: usize = 4096;
60
61pub const ICMPV6_NS_HEADER_SIZE: usize = 32;
62pub const ICMPV6_RS_HEADER_SIZE: usize = 16;
63// pub const ICMPV6_NA_HEADER_SIZE: usize = 32;
64pub const ICMPV6_ER_HEADER_SIZE: usize = 8;
65pub const ICMPV6_NI_HEADER_SIZE: usize = 32;
66
67/// If the ICMP message is a Destination Unreachable,
68/// Time Exceeded, Parameter Problem, or Source Quench,
69/// the Internet header plus the first 64 bits of the original datagram's data are returned.
70/// The remaining 32 bits of the ICMP message header are unused and must be zero.
71/// --- From RFC 792 – Internet Control Message Protocol (ICMP) https://datatracker.ietf.org/doc/html/rfc792#page-6
72fn get_icmp_payload(icmp_packet: &IcmpPacket) -> Vec<u8> {
73    let icmp_type = icmp_packet.get_icmp_type();
74    let icmp_payload = icmp_packet.payload().to_vec();
75    if icmp_type == IcmpType(3) {
76        // Destination Unreachable
77        icmp_payload[4..].to_vec()
78    } else if icmp_type == IcmpType(0) {
79        // Source Quench - Deprecated
80        icmp_payload[4..].to_vec()
81    } else if icmp_type == IcmpType(11) {
82        // Time Exceeded
83        icmp_payload[4..].to_vec()
84    } else {
85        icmp_payload
86    }
87}
88
89fn get_icmpv6_payload(icmpv6_packet: &Icmpv6Packet) -> Vec<u8> {
90    let icmpv6_type = icmpv6_packet.get_icmpv6_type();
91    let icmpv6_payload = icmpv6_packet.payload().to_vec();
92    if icmpv6_type == Icmpv6Type(1) {
93        // Destination Unreachable
94        icmpv6_payload[4..].to_vec()
95    } else if icmpv6_type == Icmpv6Type(3) {
96        // Time Exceeded
97        icmpv6_payload[4..].to_vec()
98    } else if icmpv6_type == Icmpv6Type(4) {
99        // Parameter Problem
100        icmpv6_payload[4..].to_vec()
101    } else if icmpv6_type == Icmpv6Type(128) || icmpv6_type == Icmpv6Type(129) {
102        // Echo Request/Reply
103        icmpv6_payload[4..].to_vec()
104    } else {
105        icmpv6_payload
106    }
107}
108
109pub fn find_interface_by_index(if_index: u32) -> Option<NetworkInterface> {
110    for interface in interfaces() {
111        if if_index == interface.index {
112            return Some(interface);
113        }
114    }
115    None
116}
117
118/// Use source IP address to find local interface
119pub fn find_interface_by_src(src_addr: IpAddr) -> Option<NetworkInterface> {
120    for interface in interfaces() {
121        for ip in &interface.ips {
122            let i = ip.ip();
123            if src_addr == i {
124                return Some(interface);
125            }
126        }
127    }
128    None
129}
130
131/// When the target is a loopback address,
132/// we need to update not only the value of src addr,
133/// but also the value of dst addr.
134#[derive(Debug, Clone, Copy)]
135pub struct InferAddr {
136    pub dst_addr: IpAddr,
137    pub src_addr: IpAddr,
138}
139
140impl InferAddr {
141    /// Returns: (dst_addr, src_addr)
142    pub fn ipv4_addr(&self) -> Result<(Ipv4Addr, Ipv4Addr), PistolError> {
143        if let IpAddr::V4(dst_ipv4) = self.dst_addr {
144            if let IpAddr::V4(src_ipv4) = self.src_addr {
145                return Ok((dst_ipv4, src_ipv4));
146            }
147        }
148        Err(PistolError::CanNotFoundSourceAddress)
149    }
150    /// Returns: (dst_addr, src_addr)
151    pub fn ipv6_addr(&self) -> Result<(Ipv6Addr, Ipv6Addr), PistolError> {
152        if let IpAddr::V6(dst_ipv6) = self.dst_addr {
153            if let IpAddr::V6(src_ipv6) = self.src_addr {
154                return Ok((dst_ipv6, src_ipv6));
155            }
156        }
157        Err(PistolError::CanNotFoundSourceAddress)
158    }
159}
160
161/// The source address is inferred from the target address.
162/// When the target address is a loopback address,
163/// it is mapped to an internal private address
164/// because the loopback address only works at the transport layer
165/// and cannot send data frames.
166pub fn infer_addr(
167    dst_addr: IpAddr,
168    src_addr: Option<IpAddr>,
169) -> Result<Option<InferAddr>, PistolError> {
170    if dst_addr.is_loopback() {
171        for interface in interfaces() {
172            if !interface.is_loopback() {
173                for ipn in interface.ips {
174                    match ipn.ip() {
175                        IpAddr::V4(src_ipv4) => {
176                            if dst_addr.is_ipv4() && src_ipv4.is_private() {
177                                let ia = InferAddr {
178                                    dst_addr: src_ipv4.into(),
179                                    src_addr: src_ipv4.into(),
180                                };
181                                return Ok(Some(ia));
182                            }
183                        }
184                        IpAddr::V6(src_ipv6) => {
185                            if dst_addr.is_ipv6()
186                                && (src_ipv6.is_unicast_link_local() || src_ipv6.is_unique_local())
187                            {
188                                let ia = InferAddr {
189                                    dst_addr: src_ipv6.into(),
190                                    src_addr: src_ipv6.into(),
191                                };
192                                return Ok(Some(ia));
193                            }
194                        }
195                    }
196                }
197            }
198        }
199    } else {
200        match src_addr {
201            Some(src_addr) => {
202                let ia = InferAddr { dst_addr, src_addr };
203                return Ok(Some(ia));
204            }
205            None => match search_route_table(dst_addr)? {
206                // Try to get the interface for sending through the system routing table,
207                // and then get the IP on it through the interface.
208                Some(route_info) => {
209                    for ipn in route_info.dev.ips {
210                        match ipn.ip() {
211                            IpAddr::V4(src_ipv4) => {
212                                if dst_addr.is_ipv4() && !src_ipv4.is_loopback() {
213                                    let ia = InferAddr {
214                                        dst_addr,
215                                        src_addr: src_ipv4.into(),
216                                    };
217                                    return Ok(Some(ia));
218                                }
219                            }
220                            IpAddr::V6(src_ipv6) => {
221                                if dst_addr.is_ipv6() && !src_ipv6.is_loopback() {
222                                    let ia = InferAddr {
223                                        dst_addr,
224                                        src_addr: src_ipv6.into(),
225                                    };
226                                    return Ok(Some(ia));
227                                }
228                            }
229                        }
230                    }
231                }
232                None => {
233                    // When the above methods do not work,
234                    // try to find an IP address in the same subnet as the target address
235                    // in the local interface as the source address.
236                    for interface in interfaces() {
237                        for ipn in interface.ips {
238                            if ipn.contains(dst_addr) {
239                                let src_addr = ipn.ip();
240                                let ia = InferAddr { dst_addr, src_addr };
241                                return Ok(Some(ia));
242                            }
243                        }
244                    }
245                    // Finally, if we really can't find the source address,
246                    // transform it to the address in the same network segment as the default route.
247                    let (default_route, default_route6) = get_default_route()?;
248                    let dr = if dst_addr.is_ipv4() {
249                        if let Some(dr_ipv4) = default_route {
250                            dr_ipv4
251                        } else {
252                            return Err(PistolError::CanNotFoundRouterAddress);
253                        }
254                    } else {
255                        if let Some(dr_ipv6) = default_route6 {
256                            dr_ipv6
257                        } else {
258                            return Err(PistolError::CanNotFoundRouterAddress);
259                        }
260                    };
261                    for interface in interfaces() {
262                        for ipn in interface.ips {
263                            if ipn.contains(dr.via) {
264                                let src_addr = ipn.ip();
265                                let ia = InferAddr { dst_addr, src_addr };
266                                return Ok(Some(ia));
267                            }
268                        }
269                    }
270                }
271            },
272        }
273    }
274    Ok(None)
275}
276
277#[derive(Debug, Clone, Copy)]
278pub struct Layer2Match {
279    pub name: &'static str,
280    pub src_mac: Option<MacAddr>,         // response packet src mac
281    pub dst_mac: Option<MacAddr>,         // response packet dst mac
282    pub ethernet_type: Option<EtherType>, // reponse packet ethernet type
283}
284
285impl Layer2Match {
286    pub fn do_match(&self, ethernet_packet: &[u8]) -> bool {
287        let ethernet_packet = match EthernetPacket::new(&ethernet_packet) {
288            Some(ethernet_packet) => ethernet_packet,
289            None => return false,
290        };
291        match self.src_mac {
292            Some(src_mac) => {
293                if ethernet_packet.get_source() != src_mac {
294                    return false; // early stop
295                }
296            }
297            None => (), // wild match
298        };
299
300        match self.dst_mac {
301            Some(dst_mac) => {
302                if ethernet_packet.get_destination() != dst_mac {
303                    return false;
304                }
305            }
306            None => (),
307        };
308        match self.ethernet_type {
309            Some(ethernet_type) => {
310                if ethernet_type != ethernet_packet.get_ethertype() {
311                    return false;
312                }
313            }
314            None => (),
315        };
316        true
317    }
318}
319
320#[derive(Debug, Clone, Copy)]
321pub struct Layer3Match {
322    pub name: &'static str,
323    pub layer2: Option<Layer2Match>,
324    pub src_addr: Option<IpAddr>, // response packet
325    pub dst_addr: Option<IpAddr>, // response packet
326}
327
328impl Layer3Match {
329    pub fn do_match(&self, ethernet_packet: &[u8]) -> bool {
330        let m1 = match &self.layer2 {
331            Some(layers) => layers.do_match(ethernet_packet),
332            None => true,
333        };
334        if !m1 {
335            // early stop
336            return false;
337        }
338        let ethernet_packet = match EthernetPacket::new(&ethernet_packet) {
339            Some(ethernet_packet) => ethernet_packet,
340            None => return false,
341        };
342        match ethernet_packet.get_ethertype() {
343            EtherTypes::Ipv4 => {
344                let ipv4_packet = match Ipv4Packet::new(ethernet_packet.payload()) {
345                    Some(i) => i,
346                    None => return false,
347                };
348                match self.src_addr {
349                    Some(src_addr) => match src_addr {
350                        IpAddr::V4(src_ipv4) => {
351                            if ipv4_packet.get_source() != src_ipv4 {
352                                return false;
353                            }
354                        }
355                        _ => return false,
356                    },
357                    None => (),
358                }
359                match self.dst_addr {
360                    Some(dst_addr) => match dst_addr {
361                        IpAddr::V4(dst_ipv4) => {
362                            if ipv4_packet.get_destination() != dst_ipv4 {
363                                return false;
364                            }
365                        }
366                        _ => return false,
367                    },
368                    None => (),
369                }
370                true
371            }
372            EtherTypes::Ipv6 => {
373                let ipv6_packet = match Ipv6Packet::new(ethernet_packet.payload()) {
374                    Some(i) => i,
375                    None => return false,
376                };
377                match self.src_addr {
378                    Some(src_addr) => match src_addr {
379                        IpAddr::V6(src_ipv6) => {
380                            if ipv6_packet.get_source() != src_ipv6 {
381                                return false;
382                            }
383                        }
384                        _ => return false,
385                    },
386                    None => (),
387                }
388                match self.dst_addr {
389                    Some(dst_addr) => match dst_addr {
390                        IpAddr::V6(dst_ipv6) => {
391                            if ipv6_packet.get_destination() != dst_ipv6 {
392                                return false;
393                            }
394                        }
395                        _ => return false,
396                    },
397                    None => (),
398                }
399                true
400            }
401            EtherTypes::Arp => {
402                // ARP is on layer 2.5, but here we consider it as layer 3.
403                let arp_packet = match ArpPacket::new(ethernet_packet.payload()) {
404                    Some(a) => a,
405                    None => return false,
406                };
407                match self.src_addr {
408                    Some(src_addr) => match src_addr {
409                        IpAddr::V4(src_ipv4) => {
410                            if arp_packet.get_sender_proto_addr() != src_ipv4 {
411                                return false;
412                            }
413                        }
414                        _ => return false,
415                    },
416                    None => (),
417                }
418                match self.dst_addr {
419                    Some(dst_addr) => match dst_addr {
420                        IpAddr::V4(dst_ipv4) => {
421                            if arp_packet.get_target_proto_addr() != dst_ipv4 {
422                                return false;
423                            }
424                        }
425                        _ => return false,
426                    },
427                    None => (),
428                };
429                true
430            }
431            _ => false,
432        }
433    }
434}
435
436#[derive(Debug, Clone, Copy)]
437pub struct Layer4MatchTcpUdp {
438    pub name: &'static str,
439    pub layer3: Option<Layer3Match>,
440    pub src_port: Option<u16>, // response tcp or udp packet src port
441    pub dst_port: Option<u16>, // response tcp or udp packet dst port
442}
443
444/// for debug use, return (src_ip, dst_ip)
445#[allow(dead_code)]
446fn get_ip(ethernet_packet: &[u8]) -> Option<(IpAddr, IpAddr)> {
447    let ethernet_packet = match EthernetPacket::new(&ethernet_packet) {
448        Some(ethernet_packet) => ethernet_packet,
449        None => return None,
450    };
451
452    match ethernet_packet.get_ethertype() {
453        EtherTypes::Ipv4 => {
454            let ipv4_packet = match Ipv4Packet::new(ethernet_packet.payload()) {
455                Some(i) => i,
456                None => return None,
457            };
458            Some((
459                ipv4_packet.get_source().into(),
460                ipv4_packet.get_destination().into(),
461            ))
462        }
463        EtherTypes::Ipv6 => {
464            let ipv6_packet = match Ipv6Packet::new(ethernet_packet.payload()) {
465                Some(i) => i,
466                None => return None,
467            };
468            Some((
469                ipv6_packet.get_source().into(),
470                ipv6_packet.get_destination().into(),
471            ))
472        }
473        _ => None,
474    }
475}
476
477impl Layer4MatchTcpUdp {
478    pub fn do_match(&self, ethernet_packet: &[u8]) -> bool {
479        // let mut is_debug = false;
480        // if let Some((src_ip, dst_ip)) = get_ip(ethernet_packet) {
481        //     let src_ipv4 = Ipv4Addr::new(192, 168, 1, 3);
482        //     let dst_ipv4 = Ipv4Addr::new(192, 168, 5, 3);
483        //     if src_ip == src_ipv4 && dst_ip == dst_ipv4 {
484        //         is_debug = true;
485        //     }
486        // }
487
488        let m1 = match &self.layer3 {
489            Some(layer3) => layer3.do_match(ethernet_packet),
490            None => true,
491        };
492        // if is_debug {
493        //     println!("m1: {}", m1);
494        // }
495        if !m1 {
496            // early stop
497            return false;
498        }
499        let ethernet_packet = match EthernetPacket::new(&ethernet_packet) {
500            Some(ethernet_packet) => ethernet_packet,
501            None => return false,
502        };
503        let (r_src_port, r_dst_port) = match ethernet_packet.get_ethertype() {
504            EtherTypes::Ipv4 => {
505                let ipv4_packet = match Ipv4Packet::new(ethernet_packet.payload()) {
506                    Some(i) => i,
507                    None => return false,
508                };
509                match ipv4_packet.get_next_level_protocol() {
510                    IpNextHeaderProtocols::Tcp => {
511                        let tcp_packet = match TcpPacket::new(ipv4_packet.payload()) {
512                            Some(t) => t,
513                            None => return false,
514                        };
515                        (tcp_packet.get_source(), tcp_packet.get_destination())
516                    }
517                    IpNextHeaderProtocols::Udp => {
518                        let udp_packet = match UdpPacket::new(ipv4_packet.payload()) {
519                            Some(t) => t,
520                            None => return false,
521                        };
522                        (udp_packet.get_source(), udp_packet.get_destination())
523                    }
524                    _ => (0, 0),
525                }
526            }
527            EtherTypes::Ipv6 => {
528                let ipv6_packet = match Ipv6Packet::new(ethernet_packet.payload()) {
529                    Some(i) => i,
530                    None => return false,
531                };
532                match ipv6_packet.get_next_header() {
533                    IpNextHeaderProtocols::Tcp => {
534                        let tcp_packet = match TcpPacket::new(ipv6_packet.payload()) {
535                            Some(t) => t,
536                            None => return false,
537                        };
538                        (tcp_packet.get_source(), tcp_packet.get_destination())
539                    }
540                    IpNextHeaderProtocols::Udp => {
541                        let udp_packet = match UdpPacket::new(ipv6_packet.payload()) {
542                            Some(t) => t,
543                            None => return false,
544                        };
545                        (udp_packet.get_source(), udp_packet.get_destination())
546                    }
547                    _ => (0, 0),
548                }
549            }
550            _ => (0, 0),
551        };
552        // if is_debug {
553        //     println!("read to match src port");
554        // }
555        match self.src_port {
556            Some(src_port) => {
557                if src_port != r_src_port {
558                    return false;
559                }
560            }
561            None => (),
562        };
563        // if is_debug {
564        //     println!("src port pass");
565        //     println!(
566        //         "next dst_port: {:?}, r_dst_port: {}",
567        //         self.dst_port, r_dst_port
568        //     );
569        // }
570        match self.dst_port {
571            Some(dst_port) => {
572                if dst_port != r_dst_port {
573                    return false;
574                }
575            }
576            None => (),
577        };
578        // if is_debug {
579        //     println!("dst port pass");
580        // }
581        true
582    }
583}
584
585/// Matches network layer data in icmp payload
586#[derive(Debug, Clone, Copy)]
587pub struct PayloadMatchIp {
588    pub src_addr: Option<IpAddr>, // response packet
589    pub dst_addr: Option<IpAddr>, // response packet
590}
591
592impl PayloadMatchIp {
593    /// When the icmp payload contains ipv4 data
594    pub fn do_match_ipv4(&self, icmp_payload: &[u8]) -> bool {
595        let ipv4_packet = match Ipv4Packet::new(icmp_payload) {
596            Some(i) => i,
597            None => return false,
598        };
599        match self.src_addr {
600            Some(src_addr) => match src_addr {
601                IpAddr::V4(src_ipv4) => {
602                    if ipv4_packet.get_source() != src_ipv4 {
603                        return false;
604                    }
605                }
606                _ => return false,
607            },
608            None => (),
609        }
610        match self.dst_addr {
611            Some(dst_addr) => match dst_addr {
612                IpAddr::V4(dst_ipv4) => {
613                    if ipv4_packet.get_destination() != dst_ipv4 {
614                        return false;
615                    }
616                }
617                _ => return false,
618            },
619            None => (),
620        }
621        true
622    }
623    /// When the icmp payload contains ipv6 data, and generally, icmpv6 is used at this time
624    pub fn do_match_ipv6(&self, icmpv6_payload: &[u8]) -> bool {
625        let ipv6_packet = match Ipv6Packet::new(icmpv6_payload) {
626            Some(i) => i,
627            None => return false,
628        };
629        match self.src_addr {
630            Some(src_addr) => match src_addr {
631                IpAddr::V6(src_ipv6) => {
632                    if ipv6_packet.get_source() != src_ipv6 {
633                        return false;
634                    }
635                }
636                _ => return false,
637            },
638            None => (),
639        };
640        match self.dst_addr {
641            Some(dst_addr) => match dst_addr {
642                IpAddr::V6(dst_ipv6) => {
643                    if ipv6_packet.get_destination() != dst_ipv6 {
644                        return false;
645                    }
646                }
647                _ => return false,
648            },
649            None => (),
650        }
651        true
652    }
653}
654
655/// Matches the transport layer data in icmp payload
656#[derive(Debug, Clone, Copy)]
657pub struct PayloadMatchTcpUdp {
658    pub layer3: Option<PayloadMatchIp>,
659    pub src_port: Option<u16>, // response tcp or udp packet src port
660    pub dst_port: Option<u16>, // response tcp or udp packet dst port
661}
662
663impl PayloadMatchTcpUdp {
664    pub fn do_match_ipv4(&self, icmp_payload: &[u8]) -> bool {
665        let m1 = match self.layer3 {
666            Some(layer3) => layer3.do_match_ipv4(icmp_payload),
667            None => true,
668        };
669        if !m1 {
670            // early stop
671            return false;
672        }
673        let ipv4_packet = match Ipv4Packet::new(icmp_payload) {
674            Some(i) => i,
675            None => return false,
676        };
677        let (r_src_port, r_dst_port) = match ipv4_packet.get_next_level_protocol() {
678            IpNextHeaderProtocols::Tcp => {
679                let tcp_packet = match TcpPacket::new(ipv4_packet.payload()) {
680                    Some(t) => t,
681                    None => return false,
682                };
683                (tcp_packet.get_source(), tcp_packet.get_destination())
684            }
685            IpNextHeaderProtocols::Udp => {
686                let udp_packet = match UdpPacket::new(ipv4_packet.payload()) {
687                    Some(t) => t,
688                    None => return false,
689                };
690                (udp_packet.get_source(), udp_packet.get_destination())
691            }
692            _ => (0, 0),
693        };
694        match self.src_port {
695            Some(src_port) => {
696                if src_port != r_src_port {
697                    return false;
698                }
699            }
700            None => (),
701        }
702        match self.dst_port {
703            Some(dst_port) => {
704                if dst_port != r_dst_port {
705                    return false;
706                }
707            }
708            None => (),
709        }
710        true
711    }
712    pub fn do_match_ipv6(&self, icmpv6_payload: &[u8]) -> bool {
713        let m1 = match self.layer3 {
714            Some(layer3) => layer3.do_match_ipv6(icmpv6_payload),
715            None => true,
716        };
717        if !m1 {
718            // ealry stop
719            return false;
720        }
721        let ipv6_packet = match Ipv6Packet::new(icmpv6_payload) {
722            Some(i) => i,
723            None => return false,
724        };
725        let (r_src_port, r_dst_port) = match ipv6_packet.get_next_header() {
726            IpNextHeaderProtocols::Tcp => {
727                let tcp_packet = match TcpPacket::new(ipv6_packet.payload()) {
728                    Some(t) => t,
729                    None => return false,
730                };
731                (tcp_packet.get_source(), tcp_packet.get_destination())
732            }
733            IpNextHeaderProtocols::Udp => {
734                let udp_packet = match UdpPacket::new(ipv6_packet.payload()) {
735                    Some(t) => t,
736                    None => return false,
737                };
738                (udp_packet.get_source(), udp_packet.get_destination())
739            }
740            _ => (0, 0),
741        };
742        match self.src_port {
743            Some(src_port) => {
744                if src_port != r_src_port {
745                    return false;
746                }
747            }
748            None => (),
749        }
750        match self.dst_port {
751            Some(dst_port) => {
752                if dst_port != r_dst_port {
753                    return false;
754                }
755            }
756            None => (),
757        }
758        true
759    }
760}
761
762#[derive(Debug, Clone, Copy)]
763pub struct PayloadMatchIcmp {
764    pub layer3: Option<PayloadMatchIp>,
765    pub icmp_type: Option<IcmpType>, // response icmp packet types
766    pub icmp_code: Option<IcmpCode>, // response icmp packet codes
767}
768
769impl PayloadMatchIcmp {
770    pub fn do_match(&self, icmp_payload: &[u8]) -> bool {
771        let m1 = match self.layer3 {
772            Some(layer3) => layer3.do_match_ipv4(icmp_payload),
773            None => true,
774        };
775        if !m1 {
776            // early stop
777            return false;
778        }
779        let ipv4_packet = match Ipv4Packet::new(icmp_payload) {
780            Some(i) => i,
781            None => return false,
782        };
783        let (r_type, r_code) = match ipv4_packet.get_next_level_protocol() {
784            IpNextHeaderProtocols::Icmp => match IcmpPacket::new(ipv4_packet.payload()) {
785                Some(t) => (t.get_icmp_type(), t.get_icmp_code()),
786                None => return false,
787            },
788            _ => return false,
789        };
790        match self.icmp_type {
791            Some(t) => {
792                if t != r_type {
793                    return false;
794                }
795            }
796            None => (),
797        }
798        match self.icmp_code {
799            Some(c) => {
800                if c != r_code {
801                    return false;
802                }
803            }
804            None => (),
805        }
806        true
807    }
808}
809
810#[derive(Debug, Clone, Copy)]
811pub struct PayloadMatchIcmpv6 {
812    pub layer3: Option<PayloadMatchIp>,
813    pub icmpv6_type: Option<Icmpv6Type>, // response icmp packet types
814    pub icmpv6_code: Option<Icmpv6Code>, // response icmp packet codes
815}
816
817impl PayloadMatchIcmpv6 {
818    pub fn do_match(&self, icmpv6_payload: &[u8]) -> bool {
819        let m1 = match self.layer3 {
820            Some(layer3) => layer3.do_match_ipv6(icmpv6_payload),
821            None => true,
822        };
823        if !m1 {
824            // early stop
825            return false;
826        }
827        let ipv6_packet = match Ipv6Packet::new(icmpv6_payload) {
828            Some(i) => i,
829            None => return false,
830        };
831        let (r_types, r_codes) = match ipv6_packet.get_next_header() {
832            IpNextHeaderProtocols::Icmpv6 => match Icmpv6Packet::new(ipv6_packet.payload()) {
833                Some(t) => (t.get_icmpv6_type(), t.get_icmpv6_code()),
834                None => return false,
835            },
836            _ => return false,
837        };
838        match self.icmpv6_type {
839            Some(types) => {
840                if types != r_types {
841                    return false;
842                }
843            }
844            None => (),
845        }
846        match self.icmpv6_code {
847            Some(codes) => {
848                if codes != r_codes {
849                    return false;
850                }
851            }
852            None => (),
853        }
854        true
855    }
856}
857
858#[derive(Debug, Clone, Copy)]
859pub enum PayloadMatch {
860    PayloadMatchIp(PayloadMatchIp),
861    PayloadMatchTcpUdp(PayloadMatchTcpUdp),
862    PayloadMatchIcmp(PayloadMatchIcmp),
863    PayloadMatchIcmpv6(PayloadMatchIcmpv6),
864}
865
866/// Because when icmp returns raw data as icmp packet payload,
867/// there is no indication whether it is ipv4 data or ipv6 data.
868/// But generally speaking, if ipv4 data is sent, ipv4 will be returned,
869/// and the same is true for ipv6, so users need to choose two different functions.
870impl PayloadMatch {
871    pub fn do_match_ipv4(&self, icmp_payload: &[u8]) -> bool {
872        match self {
873            PayloadMatch::PayloadMatchIp(ip) => ip.do_match_ipv4(icmp_payload),
874            PayloadMatch::PayloadMatchTcpUdp(tcp_udp) => tcp_udp.do_match_ipv4(icmp_payload),
875            PayloadMatch::PayloadMatchIcmp(icmp) => icmp.do_match(icmp_payload),
876            PayloadMatch::PayloadMatchIcmpv6(_) => false,
877        }
878    }
879    pub fn do_match_ipv6(&self, icmpv6_payload: &[u8]) -> bool {
880        match self {
881            PayloadMatch::PayloadMatchIp(ip) => ip.do_match_ipv6(icmpv6_payload),
882            PayloadMatch::PayloadMatchTcpUdp(tcp_udp) => tcp_udp.do_match_ipv4(icmpv6_payload),
883            PayloadMatch::PayloadMatchIcmpv6(icmpv6) => icmpv6.do_match(icmpv6_payload),
884            PayloadMatch::PayloadMatchIcmp(_) => false,
885        }
886    }
887}
888
889#[derive(Debug, Clone, Copy)]
890pub struct Layer4MatchIcmp {
891    pub name: &'static str,
892    pub layer3: Option<Layer3Match>,
893    pub icmp_type: Option<IcmpType>,   // response icmp packet types
894    pub icmp_code: Option<IcmpCode>,   // response icmp packet codes
895    pub payload: Option<PayloadMatch>, // used to confirm which port the data packet is from
896}
897
898impl Layer4MatchIcmp {
899    pub fn do_match(&self, ethernet_packet: &[u8]) -> bool {
900        let m1 = match &self.layer3 {
901            Some(layer3) => layer3.do_match(ethernet_packet),
902            None => true,
903        };
904        if !m1 {
905            // early stop
906            return false;
907        }
908        let ethernet_packet = match EthernetPacket::new(&ethernet_packet) {
909            Some(ethernet_packet) => ethernet_packet,
910            None => return false,
911        };
912        let (r_type, r_code, icmp_payload) = match ethernet_packet.get_ethertype() {
913            EtherTypes::Ipv4 => {
914                let ipv4_packet = match Ipv4Packet::new(ethernet_packet.payload()) {
915                    Some(i) => i,
916                    None => return false,
917                };
918                match ipv4_packet.get_next_level_protocol() {
919                    IpNextHeaderProtocols::Icmp => match IcmpPacket::new(ipv4_packet.payload()) {
920                        Some(icmp_packet) => (
921                            icmp_packet.get_icmp_type(),
922                            icmp_packet.get_icmp_code(),
923                            get_icmp_payload(&icmp_packet),
924                        ),
925                        None => return false,
926                    },
927                    _ => return false,
928                }
929            }
930            _ => return false,
931        };
932        match self.icmp_type {
933            Some(t) => {
934                if t != r_type {
935                    return false;
936                }
937            }
938            None => (),
939        }
940        match self.icmp_code {
941            Some(c) => {
942                if c != r_code {
943                    return false;
944                }
945            }
946            None => (),
947        }
948        match self.payload {
949            Some(payload) => payload.do_match_ipv4(&icmp_payload),
950            None => true,
951        }
952    }
953}
954
955#[derive(Debug, Clone, Copy)]
956pub struct Layer4MatchIcmpv6 {
957    pub name: &'static str,
958    pub layer3: Option<Layer3Match>,
959    pub icmpv6_type: Option<Icmpv6Type>, // response icmp packet types
960    pub icmpv6_code: Option<Icmpv6Code>, // response icmp packet codes
961    pub payload: Option<PayloadMatch>,
962}
963
964impl Layer4MatchIcmpv6 {
965    pub fn do_match(&self, ethernet_packet: &[u8]) -> bool {
966        let m1 = match &self.layer3 {
967            Some(layer3) => layer3.do_match(ethernet_packet),
968            None => true,
969        };
970        if !m1 {
971            // early stop
972            return false;
973        }
974
975        let ethernet_packet = match EthernetPacket::new(&ethernet_packet) {
976            Some(ethernet_packet) => ethernet_packet,
977            None => return false,
978        };
979        let (r_type, r_code, icmpv6_payload) = match ethernet_packet.get_ethertype() {
980            EtherTypes::Ipv6 => {
981                let ipv6_packet = match Ipv6Packet::new(ethernet_packet.payload()) {
982                    Some(i) => i,
983                    None => return false,
984                };
985                match ipv6_packet.get_next_header() {
986                    IpNextHeaderProtocols::Icmpv6 => {
987                        match Icmpv6Packet::new(ipv6_packet.payload()) {
988                            Some(icmpv6_packet) => (
989                                icmpv6_packet.get_icmpv6_type(),
990                                icmpv6_packet.get_icmpv6_code(),
991                                get_icmpv6_payload(&icmpv6_packet),
992                            ),
993                            None => return false,
994                        }
995                    }
996                    _ => return false,
997                }
998            }
999            _ => return false,
1000        };
1001        match self.icmpv6_type {
1002            Some(t) => {
1003                if t != r_type {
1004                    return false;
1005                }
1006            }
1007            None => (),
1008        }
1009        match self.icmpv6_code {
1010            Some(c) => {
1011                if c != r_code {
1012                    return false;
1013                }
1014            }
1015            None => (),
1016        };
1017        match self.payload {
1018            Some(payload) => payload.do_match_ipv6(&icmpv6_payload),
1019            None => true,
1020        }
1021    }
1022}
1023
1024/// or rules
1025#[allow(dead_code)]
1026#[derive(Debug, Clone, Copy)]
1027pub enum LayerMatch {
1028    Layer2Match(Layer2Match),
1029    Layer3Match(Layer3Match),
1030    Layer4MatchTcpUdp(Layer4MatchTcpUdp),
1031    Layer4MatchIcmp(Layer4MatchIcmp),
1032    Layer4MatchIcmpv6(Layer4MatchIcmpv6),
1033}
1034
1035impl LayerMatch {
1036    pub fn do_match(&self, ethernet_packet: &[u8]) -> bool {
1037        if ethernet_packet.len() > 0 {
1038            match self {
1039                LayerMatch::Layer2Match(l2) => l2.do_match(ethernet_packet),
1040                LayerMatch::Layer3Match(l3) => l3.do_match(ethernet_packet),
1041                LayerMatch::Layer4MatchTcpUdp(tcp_udp) => tcp_udp.do_match(ethernet_packet),
1042                LayerMatch::Layer4MatchIcmp(icmp) => icmp.do_match(ethernet_packet),
1043                LayerMatch::Layer4MatchIcmpv6(icmpv6) => icmpv6.do_match(ethernet_packet),
1044            }
1045        } else {
1046            false
1047        }
1048    }
1049    pub fn name(&self) -> &'static str {
1050        match self {
1051            LayerMatch::Layer2Match(l2) => l2.name,
1052            LayerMatch::Layer3Match(l3) => l3.name,
1053            LayerMatch::Layer4MatchTcpUdp(tcp_udp) => tcp_udp.name,
1054            LayerMatch::Layer4MatchIcmp(icmp) => icmp.name,
1055            LayerMatch::Layer4MatchIcmpv6(icmpv6) => icmpv6.name,
1056        }
1057    }
1058}
1059
1060/// Capture the traffic and save into file.
1061pub fn layer2_capture(packet: &[u8]) -> Result<(), PistolError> {
1062    let ppf = match PISTOL_PCAPNG_FLAG.lock() {
1063        Ok(ppf) => *ppf,
1064        Err(e) => {
1065            return Err(PistolError::TryLockGlobalVarFailed {
1066                var_name: String::from("PISTOL_PCAPNG_FLAG"),
1067                e: e.to_string(),
1068            });
1069        }
1070    };
1071
1072    if ppf {
1073        match PISTOL_PCAPNG.lock() {
1074            Ok(mut pp) => {
1075                // interface_id = 0 means we use the first interface we builed in fake pcapng headers
1076                const INTERFACE_ID: u32 = 0;
1077                // this is the default value of pcapture
1078                const SNAPLEN: usize = 65535;
1079                match EnhancedPacketBlock::new(INTERFACE_ID, packet, SNAPLEN) {
1080                    Ok(block) => {
1081                        let gb = GeneralBlock::EnhancedPacketBlock(block);
1082                        pp.append(gb);
1083                    }
1084                    Err(e) => {
1085                        error!("build EnhancedPacketBlock in layer2_send() failed: {}", e)
1086                    }
1087                }
1088            }
1089            Err(e) => {
1090                return Err(PistolError::TryLockGlobalVarFailed {
1091                    var_name: String::from("PISTOL_PCAPNG"),
1092                    e: e.to_string(),
1093                });
1094            }
1095        }
1096    }
1097    Ok(())
1098}
1099
1100/// This function only recvs data.
1101fn layer2_set_matchs(
1102    layer_matchs: Vec<LayerMatch>,
1103) -> Result<(Receiver<Vec<u8>>, PistolChannel), PistolError> {
1104    // let (tx: Sender<Vec<u8>>, rx: Receiver<Vec<PistolChannel>>) = channel();
1105    let (tx, rx) = channel();
1106    let pc = PistolChannel {
1107        uuid: Uuid::new_v4(),
1108        channel: tx,
1109        layer_matchs,
1110    };
1111
1112    match UNIFIED_RECV_MATCHS.lock() {
1113        Ok(mut urm) => urm.push(pc.clone()),
1114        Err(e) => {
1115            return Err(PistolError::TryLockGlobalVarFailed {
1116                var_name: String::from("UNIFIED_RECV_MATCHS"),
1117                e: e.to_string(),
1118            });
1119        }
1120    }
1121    Ok((rx, pc))
1122}
1123
1124fn layer2_rm_matchs(uuid: &Uuid) -> Result<bool, PistolError> {
1125    match UNIFIED_RECV_MATCHS.lock() {
1126        Ok(mut urm) => {
1127            let mut urm_clone = urm.clone();
1128            if let Some(index) = urm_clone.iter().position(|pc| pc.uuid == *uuid) {
1129                urm_clone.remove(index);
1130                *urm = urm_clone;
1131                Ok(true)
1132            } else {
1133                Ok(false)
1134            }
1135        }
1136        Err(e) => Err(PistolError::TryLockGlobalVarFailed {
1137            var_name: String::from("UNIFIED_RECV_MATCHS"),
1138            e: e.to_string(),
1139        }),
1140    }
1141}
1142
1143fn layer2_recv(rx: Receiver<Vec<u8>>, timeout: Option<Duration>) -> Result<Vec<u8>, PistolError> {
1144    let timeout = match timeout {
1145        Some(t) => t,
1146        None => Duration::from_secs_f64(DEFAULT_TIMEOUT),
1147    };
1148
1149    // only 1 packet will be recv from match threads
1150    let iter = rx.recv_timeout(timeout).into_iter().take(1);
1151    for ethernet_packet in iter {
1152        return Ok(ethernet_packet);
1153    }
1154    Ok(Vec::new())
1155}
1156
1157/// This function only sends data.
1158fn layer2_send(
1159    dst_mac: MacAddr,
1160    interface: NetworkInterface,
1161    payload: &[u8],
1162    payload_len: usize,
1163    ethernet_type: EtherType,
1164    timeout: Option<Duration>,
1165) -> Result<(), PistolError> {
1166    let config = Config {
1167        write_buffer_size: ETHERNET_BUFF_SIZE,
1168        read_buffer_size: ETHERNET_BUFF_SIZE,
1169        read_timeout: timeout,
1170        write_timeout: timeout,
1171        channel_type: ChannelType::Layer2,
1172        bpf_fd_attempts: 1000,
1173        linux_fanout: None,
1174        promiscuous: false,
1175        socket_fd: None,
1176    };
1177
1178    let (mut sender, _) = match datalink::channel(&interface, config) {
1179        Ok(Ethernet(tx, rx)) => (tx, rx),
1180        Ok(_) => return Err(PistolError::CreateDatalinkChannelFailed),
1181        Err(e) => return Err(e.into()),
1182    };
1183
1184    let src_mac = if dst_mac == MacAddr::zero() {
1185        MacAddr::zero()
1186    } else {
1187        match interface.mac {
1188            Some(m) => m,
1189            None => return Err(PistolError::CanNotFoundMacAddress),
1190        }
1191    };
1192
1193    let ethernet_buff_len = ETHERNET_HEADER_SIZE + payload_len;
1194    // According to the document, the minimum length of an Ethernet data packet is 64 bytes
1195    // (14 bytes of header and at least 46 bytes of data and 4 bytes of FCS),
1196    // but I found through packet capture that nmap did not follow this convention,
1197    // so this padding is also cancelled here.
1198    // let ethernet_buff_len = if ethernet_buff_len < 60 {
1199    //     // padding before FCS
1200    //     60
1201    // } else {
1202    //     ethernet_buff_len
1203    // };
1204    let mut buff = vec![0u8; ethernet_buff_len];
1205    let mut ethernet_packet = match MutableEthernetPacket::new(&mut buff) {
1206        Some(p) => p,
1207        None => {
1208            return Err(PistolError::BuildPacketError {
1209                location: format!("{}", Location::caller()),
1210            });
1211        }
1212    };
1213    ethernet_packet.set_destination(dst_mac);
1214    ethernet_packet.set_source(src_mac);
1215    ethernet_packet.set_ethertype(ethernet_type);
1216    ethernet_packet.set_payload(payload);
1217    layer2_capture(&buff)?;
1218
1219    match sender.send_to(&buff, Some(interface)) {
1220        Some(r) => match r {
1221            Err(e) => return Err(e.into()),
1222            _ => Ok(()),
1223        },
1224        None => Ok(()),
1225    }
1226}
1227
1228/// In order to prevent other threads from reading and discarding data packets
1229/// that do not belong to them during the multi-threaded multi-packet sending process,
1230/// and to improve the stability of the scan, I decided to put the reception of
1231/// all data packets into one thread.
1232pub fn layer2_work(
1233    dst_mac: MacAddr,
1234    interface: NetworkInterface,
1235    payload: &[u8],
1236    payload_len: usize,
1237    ethernet_type: EtherType,
1238    layer_matchs: Vec<LayerMatch>,
1239    timeout: Option<Duration>,
1240    need_return: bool,
1241) -> Result<(Vec<u8>, Duration), PistolError> {
1242    let running = match PISTOL_RUNNER_IS_RUNNING.lock() {
1243        Ok(r) => *r,
1244        Err(e) => {
1245            return Err(PistolError::TryLockGlobalVarFailed {
1246                var_name: String::from("PISTOL_RUNNER_IS_RUNNING"),
1247                e: e.to_string(),
1248            });
1249        }
1250    };
1251
1252    if running {
1253        let start = Instant::now();
1254        if need_return {
1255            // set the matchs
1256            let (rx, pc) = layer2_set_matchs(layer_matchs)?;
1257            layer2_send(
1258                dst_mac,
1259                interface,
1260                payload,
1261                payload_len,
1262                ethernet_type,
1263                timeout,
1264            )?;
1265            let data = layer2_recv(rx, timeout)?;
1266            let rtt = start.elapsed();
1267            // we done here and remove the matchs
1268            if !layer2_rm_matchs(&pc.uuid)? {
1269                warn!("can not found and remove recv matchs");
1270            }
1271            Ok((data, rtt))
1272        } else {
1273            layer2_send(
1274                dst_mac,
1275                interface,
1276                payload,
1277                payload_len,
1278                ethernet_type,
1279                timeout,
1280            )?;
1281            let rtt = start.elapsed();
1282
1283            Ok((Vec::new(), rtt))
1284        }
1285    } else {
1286        Err(PistolError::PistolRunnerIsNotRunning)
1287    }
1288}
1289
1290pub fn layer3_ipv4_send(
1291    dst_ipv4: Ipv4Addr,
1292    src_ipv4: Ipv4Addr,
1293    ethernet_payload: &[u8],
1294    layer_matchs: Vec<LayerMatch>,
1295    timeout: Option<Duration>,
1296    need_return: bool,
1297) -> Result<(Vec<u8>, Duration), PistolError> {
1298    let (dst_mac, interface) =
1299        RouteVia::get_dst_mac_and_src_if(dst_ipv4.into(), src_ipv4.into(), timeout)?;
1300    debug!(
1301        "dst addr: {}, dst mac: {}, src addr: {}, sending interface: {}, {:?}",
1302        dst_ipv4, dst_mac, src_ipv4, interface.name, interface.ips
1303    );
1304    let ethernet_type = EtherTypes::Ipv4;
1305    let payload_len = ethernet_payload.len();
1306    let (layer2_buff, rtt) = layer2_work(
1307        dst_mac,
1308        interface,
1309        ethernet_payload,
1310        payload_len,
1311        ethernet_type,
1312        layer_matchs,
1313        timeout,
1314        need_return,
1315    )?;
1316    Ok((layer2_payload(&layer2_buff), rtt))
1317}
1318
1319pub fn multicast_mac(ip: Ipv6Addr) -> MacAddr {
1320    let ip = ip.octets();
1321    // 33:33:FF:xx:xx:xx
1322    MacAddr::new(0x33, 0x33, 0xFF, ip[13], ip[14], ip[15])
1323}
1324
1325fn layer2_payload(buff: &[u8]) -> Vec<u8> {
1326    match EthernetPacket::new(buff) {
1327        Some(ethernet_packet) => ethernet_packet.payload().to_vec(),
1328        None => Vec::new(),
1329    }
1330}
1331
1332pub fn layer3_ipv6_send(
1333    dst_ipv6: Ipv6Addr,
1334    src_ipv6: Ipv6Addr,
1335    payload: &[u8],
1336    layer_matchs: Vec<LayerMatch>,
1337    timeout: Option<Duration>,
1338    need_return: bool,
1339) -> Result<(Vec<u8>, Duration), PistolError> {
1340    let dst_ipv6 = if dst_ipv6.is_loopback() {
1341        src_ipv6
1342    } else {
1343        dst_ipv6
1344    };
1345    let (dst_mac, interface) =
1346        RouteVia::get_dst_mac_and_src_if(dst_ipv6.into(), src_ipv6.into(), timeout)?;
1347
1348    let ethernet_type = EtherTypes::Ipv6;
1349    let payload_len = payload.len();
1350    let (layer2_buff, rtt) = layer2_work(
1351        dst_mac,
1352        interface,
1353        payload,
1354        payload_len,
1355        ethernet_type,
1356        layer_matchs,
1357        timeout,
1358        need_return,
1359    )?;
1360    Ok((layer2_payload(&layer2_buff), rtt))
1361}
1362
1363#[cfg(test)]
1364mod tests {
1365    use super::*;
1366    use crate::PistolLogger;
1367    use crate::PistolRunner;
1368    use pnet::packet::icmp::IcmpTypes;
1369    use pnet::packet::icmpv6::Icmpv6Types;
1370    use std::str::FromStr;
1371    #[test]
1372    fn test_infer_addr() {
1373        let _pr = PistolRunner::init(
1374            PistolLogger::Debug,
1375            None,
1376            None, // use default value
1377        )
1378        .unwrap();
1379        let dst_ipv4 = Ipv4Addr::new(192, 168, 5, 129);
1380        let ia = infer_addr(dst_ipv4.into(), None).unwrap();
1381        if let Some(ia) = ia {
1382            let timeout = Some(Duration::from_secs_f64(1.0));
1383            let (_mac, interface) =
1384                RouteVia::get_dst_mac_and_src_if(ia.dst_addr, ia.src_addr, timeout).unwrap();
1385            println!("{}", interface.name);
1386        }
1387        println!("{:?}", ia);
1388    }
1389    #[test]
1390    fn test_layer_match() {
1391        let data: Vec<u8> = vec![
1392            0x0, 0xc, 0x29, 0x5b, 0xbd, 0x5c, 0x0, 0xc, 0x29, 0x2c, 0x9, 0xe4, 0x8, 0x0, 0x45,
1393            0xc0, 0x0, 0x38, 0x1, 0xcd, 0x0, 0x0, 0x40, 0x1, 0xec, 0xdf, 0xc0, 0xa8, 0x5, 0x5,
1394            0xc0, 0xa8, 0x5, 0x3, 0x3, 0x3, 0x88, 0x6f, 0x0, 0x0, 0x0, 0x0, 0x45, 0x0, 0x0, 0x1c,
1395            0x81, 0x56, 0x40, 0x0, 0x40, 0x11, 0x2e, 0x22, 0xc0, 0xa8, 0x5, 0x3, 0xc0, 0xa8, 0x5,
1396            0x5, 0x73, 0xa, 0x1f, 0x90, 0x0, 0x8, 0xe1, 0xea,
1397        ];
1398        let dst_ipv4 = Ipv4Addr::new(192, 168, 5, 5);
1399        let src_ipv4 = Ipv4Addr::new(192, 168, 5, 3);
1400        let dst_port = 8080;
1401        let src_port = 29450;
1402        let layer3 = Layer3Match {
1403            name: "test layer3",
1404            layer2: None,
1405            src_addr: Some(dst_ipv4.into()),
1406            dst_addr: Some(src_ipv4.into()),
1407        };
1408        let payload_ip = PayloadMatchIp {
1409            src_addr: Some(src_ipv4.into()),
1410            dst_addr: Some(dst_ipv4.into()),
1411        };
1412        let payload_tcp_udp = PayloadMatchTcpUdp {
1413            layer3: Some(payload_ip),
1414            src_port: Some(src_port),
1415            dst_port: Some(dst_port),
1416        };
1417        let payload = PayloadMatch::PayloadMatchTcpUdp(payload_tcp_udp);
1418        let layer4_icmp = Layer4MatchIcmp {
1419            name: "test icmp",
1420            layer3: Some(layer3),
1421            icmp_type: None,
1422            icmp_code: None,
1423            payload: Some(payload),
1424        };
1425        let layer_match = LayerMatch::Layer4MatchIcmp(layer4_icmp);
1426        let x = layer_match.do_match(&data);
1427        println!("match ret: {}", x);
1428    }
1429    #[test]
1430    fn test_layer_match2() {
1431        let data = vec![
1432            0x0, 0xc, 0x29, 0x5b, 0xbd, 0x5c, 0x0, 0xc, 0x29, 0x2c, 0x9, 0xe4, 0x86, 0xdd, 0x60,
1433            0x0, 0x0, 0x0, 0x0, 0x20, 0x3a, 0xff, 0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2,
1434            0xc, 0x29, 0xff, 0xfe, 0x2c, 0x9, 0xe4, 0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2,
1435            0xc, 0x29, 0xff, 0xfe, 0x5b, 0xbd, 0x5c, 0x88, 0x0, 0x97, 0x8, 0x60, 0x0, 0x0, 0x0,
1436            0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xc, 0x29, 0xff, 0xfe, 0x2c, 0x9, 0xe4,
1437            0x2, 0x1, 0x0, 0xc, 0x29, 0x2c, 0x9, 0xe4,
1438        ];
1439        let dst_ipv6 = Ipv6Addr::from_str("fe80::20c:29ff:fe2c:9e4").unwrap();
1440        let src_ipv6 = Ipv6Addr::from_str("fe80::20c:29ff:fe5b:bd5c").unwrap();
1441        let layer3 = Layer3Match {
1442            name: "test layer3",
1443            layer2: None,
1444            src_addr: Some(dst_ipv6.into()),
1445            dst_addr: Some(src_ipv6.into()),
1446        };
1447        let layer4_icmpv6 = Layer4MatchIcmpv6 {
1448            name: "test icmpv6",
1449            layer3: Some(layer3),
1450            icmpv6_type: Some(Icmpv6Types::NeighborAdvert),
1451            icmpv6_code: None,
1452            payload: None,
1453        };
1454        let layer_match = LayerMatch::Layer4MatchIcmpv6(layer4_icmpv6);
1455        let x = layer_match.do_match(&data);
1456        println!("match ret: {}", x);
1457    }
1458    #[test]
1459    fn test_layer_match3() {
1460        let src_ipv4 = Ipv4Addr::new(192, 168, 5, 3);
1461        let dst_ipv4 = Ipv4Addr::new(192, 168, 1, 3);
1462        let src_port = 45982;
1463        let dst_port = 33434;
1464        let layer3 = Layer3Match {
1465            name: "test layer3",
1466            layer2: None,
1467            src_addr: None,
1468            dst_addr: Some(src_ipv4.into()),
1469        };
1470        // set the icmp payload matchs
1471        let payload_ip = PayloadMatchIp {
1472            src_addr: Some(src_ipv4.into()),
1473            dst_addr: Some(dst_ipv4.into()),
1474        };
1475        let payload_tcp_udp = PayloadMatchTcpUdp {
1476            layer3: Some(payload_ip),
1477            src_port: Some(src_port),
1478            dst_port: Some(dst_port),
1479        };
1480        let payload = PayloadMatch::PayloadMatchTcpUdp(payload_tcp_udp);
1481        let layer4_icmp = Layer4MatchIcmp {
1482            name: "test icmp",
1483            layer3: Some(layer3),
1484            icmp_type: Some(IcmpTypes::TimeExceeded),
1485            icmp_code: None,
1486            payload: Some(payload),
1487        };
1488        let layer_match_icmp_time_exceeded = LayerMatch::Layer4MatchIcmp(layer4_icmp);
1489
1490        let data = vec![
1491            0x0, 0xc, 0x29, 0x5b, 0xbd, 0x5c, 0x0, 0x50, 0x56, 0xff, 0xa6, 0x97, 0x8, 0x0, 0x45,
1492            0x0, 0x0, 0x58, 0xe, 0x7f, 0x0, 0x0, 0x80, 0x1, 0xa0, 0xd0, 0xc0, 0xa8, 0x5, 0x2, 0xc0,
1493            0xa8, 0x5, 0x3, 0xb, 0x0, 0x7c, 0x90, 0x0, 0x0, 0x0, 0x0, 0x45, 0x0, 0x0, 0x3c, 0x9b,
1494            0x2f, 0x40, 0x0, 0x1, 0x11, 0x57, 0x2b, 0xc0, 0xa8, 0x5, 0x3, 0xc0, 0xa8, 0x1, 0x3,
1495            0xb3, 0x9e, 0x82, 0x9a, 0x0, 0x28, 0x4d, 0x9, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
1496            0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54,
1497            0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
1498        ];
1499
1500        let ret = layer_match_icmp_time_exceeded.do_match(&data);
1501        println!("{}", ret);
1502    }
1503    #[test]
1504    fn test_layer_match4() {
1505        let src_ipv4 = Ipv4Addr::new(192, 168, 5, 3);
1506        let dst_ipv4 = Ipv4Addr::new(192, 168, 1, 3);
1507        let src_port = 59470;
1508        let dst_port = 80;
1509
1510        let layer3 = Layer3Match {
1511            name: "test layer3",
1512            layer2: None,
1513            src_addr: None, // usually this is the address of the router, not the address of the target machine.
1514            dst_addr: Some(src_ipv4.into()),
1515        };
1516        let payload_ip = PayloadMatchIp {
1517            src_addr: Some(src_ipv4.into()),
1518            dst_addr: Some(dst_ipv4.into()),
1519        };
1520        let payload_tcp_udp = PayloadMatchTcpUdp {
1521            layer3: Some(payload_ip),
1522            src_port: Some(src_port),
1523            dst_port: Some(dst_port),
1524        };
1525        let payload = PayloadMatch::PayloadMatchTcpUdp(payload_tcp_udp);
1526        let layer4_icmp = Layer4MatchIcmp {
1527            name: "test icmp",
1528            layer3: Some(layer3),
1529            icmp_type: Some(IcmpTypes::TimeExceeded),
1530            icmp_code: None,
1531            payload: Some(payload),
1532        };
1533        let layer_match_icmp_time_exceeded = LayerMatch::Layer4MatchIcmp(layer4_icmp);
1534
1535        let data = vec![
1536            0x0, 0xc, 0x29, 0x5b, 0xbd, 0x5c, 0x0, 0x50, 0x56, 0xff, 0xa6, 0x97, 0x8, 0x0, 0x45,
1537            0x0, 0x0, 0x58, 0x7, 0x5e, 0x0, 0x0, 0x80, 0x1, 0xa7, 0xf1, 0xc0, 0xa8, 0x5, 0x2, 0xc0,
1538            0xa8, 0x5, 0x3, 0xb, 0x0, 0x7c, 0x85, 0x0, 0x0, 0x0, 0x0, 0x45, 0x0, 0x0, 0x3c, 0x8a,
1539            0x1f, 0x40, 0x0, 0x1, 0x6, 0x68, 0x46, 0xc0, 0xa8, 0x5, 0x3, 0xc0, 0xa8, 0x1, 0x3,
1540            0xe8, 0x4e, 0x0, 0x50, 0xb9, 0xc5, 0x70, 0x4a, 0x0, 0x0, 0x0, 0x0, 0xa0, 0x2, 0x16,
1541            0xd0, 0xf2, 0x92, 0x0, 0x0, 0x2, 0x4, 0x5, 0xb4, 0x4, 0x2, 0x8, 0xa, 0x78, 0x46, 0x2c,
1542            0x56, 0x0, 0x0, 0x0, 0x0, 0x1, 0x3, 0x3, 0x2,
1543        ];
1544
1545        let ret = layer_match_icmp_time_exceeded.do_match(&data);
1546        println!("{}", ret);
1547    }
1548    #[test]
1549    fn test_layer_match5() {
1550        let src_ipv4 = Ipv4Addr::new(192, 168, 5, 3);
1551        let dst_ipv4 = Ipv4Addr::new(192, 168, 1, 3);
1552        let src_port = 26845;
1553        let dst_port = 80;
1554
1555        let layer3 = Layer3Match {
1556            name: "test layer3",
1557            layer2: None,
1558            src_addr: Some(dst_ipv4.into()),
1559            dst_addr: Some(src_ipv4.into()),
1560        };
1561        let layer4_tcp_udp = Layer4MatchTcpUdp {
1562            name: "test tcp_udp",
1563            layer3: Some(layer3),
1564            src_port: Some(dst_port),
1565            dst_port: Some(src_port),
1566        };
1567        let layer_match_tcp = LayerMatch::Layer4MatchTcpUdp(layer4_tcp_udp);
1568
1569        let data = [
1570            0x0, 0xc, 0x29, 0x5b, 0xbd, 0x5c, 0x0, 0x50, 0x56, 0xff, 0xa6, 0x97, 0x8, 0x0, 0x45,
1571            0x0, 0x0, 0x28, 0xd, 0x83, 0x0, 0x0, 0x80, 0x6, 0xa5, 0xf6, 0xc0, 0xa8, 0x1, 0x3, 0xc0,
1572            0xa8, 0x5, 0x3, 0x0, 0x50, 0x68, 0xdd, 0x48, 0xc4, 0x1, 0xc5, 0xbf, 0x34, 0xcb, 0x88,
1573            0x50, 0x14, 0xfa, 0xf0, 0xef, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
1574        ];
1575
1576        let ret = layer_match_tcp.do_match(&data);
1577        println!("{}", ret);
1578    }
1579    #[test]
1580    fn test_layer2_send() {
1581        let config = Config {
1582            write_buffer_size: ETHERNET_BUFF_SIZE,
1583            read_buffer_size: ETHERNET_BUFF_SIZE,
1584            read_timeout: Some(Duration::new(1, 0)),
1585            write_timeout: Some(Duration::new(1, 0)),
1586            channel_type: ChannelType::Layer2,
1587            bpf_fd_attempts: 1000,
1588            linux_fanout: None,
1589            promiscuous: false,
1590            socket_fd: None,
1591        };
1592
1593        // let dst_ipv4 = Ipv4Addr::new(192, 168, 5, 5);
1594        let src_ipv4 = Ipv4Addr::new(192, 168, 5, 3);
1595        let interface = find_interface_by_src(src_ipv4.into()).unwrap();
1596
1597        let (mut sender, _) = match datalink::channel(&interface, config) {
1598            Ok(Ethernet(tx, rx)) => (tx, rx),
1599            _ => panic!("create datalink channel failed"),
1600        };
1601
1602        // let data: Vec<u8> = vec![
1603        //     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x45, 0x0, 0x0,
1604        //     0x3c, 0x84, 0x7c, 0x40, 0x0, 0x40, 0x6, 0xb8, 0x3d, 0x7f, 0x0, 0x0, 0x1, 0x7f, 0x0,
1605        //     0x0, 0x1, 0xbb, 0xee, 0x0, 0x50, 0xe4, 0xdf, 0xeb, 0x16, 0x0, 0x0, 0x0, 0x0, 0xa0, 0x2,
1606        //     0xff, 0xd7, 0xfe, 0x30, 0x0, 0x0, 0x2, 0x4, 0xff, 0xd7, 0x4, 0x2, 0x8, 0xa, 0xd4, 0xb8,
1607        //     0xfd, 0x6, 0x0, 0x0, 0x0, 0x0, 0x1, 0x3, 0x3, 0x7,
1608        // ];
1609        let data: Vec<u8> = vec![
1610            0x0, 0xc, 0x29, 0x2c, 0x9, 0xe4, 0x0, 0xc, 0x29, 0x5b, 0xbd, 0x5c, 0x8, 0x0, 0x45, 0x0,
1611            0x0, 0x28, 0x40, 0xaa, 0x0, 0x0, 0x3a, 0x6, 0xb4, 0xcd, 0xc0, 0xa8, 0x5, 0x3, 0xc0,
1612            0xa8, 0x5, 0x5, 0xc7, 0xec, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, 0x99, 0xb7, 0x60, 0xf6,
1613            0x50, 0x10, 0x4, 0x0, 0x5d, 0x91, 0x0, 0x0,
1614        ];
1615        let _ = sender.send_to(&data, Some(interface)).unwrap();
1616    }
1617}