mirror of
https://github.com/ivre/masscanned.git
synced 2025-10-02 06:38:21 +00:00
commit
7590b02a2f
15 changed files with 748 additions and 72 deletions
25
README.md
25
README.md
|
@ -290,12 +290,27 @@ tcpdump: pcap_loop: The interface disappeared
|
|||
0 packets dropped by kernel
|
||||
```
|
||||
|
||||
### Logging Policy
|
||||
## Logging
|
||||
|
||||
* `ERR`: any error - will always be displayed.
|
||||
* `WARN`, `-v`: responses sent by `masscanned`.
|
||||
* `INFO`, `-vv`: packets not handled, packets ignored.
|
||||
* `DEBUG`, `-vvv`: all packets received and sent by `masscanned`.
|
||||
### Console Logger
|
||||
|
||||
**Verbs**:
|
||||
* `init`
|
||||
* `recv`
|
||||
* `send`
|
||||
* `drop`
|
||||
|
||||
#### ARP
|
||||
|
||||
```
|
||||
$ts arp $verb $operation $client_mac $client_ip $masscanned_mac $masscanned_ip
|
||||
```
|
||||
|
||||
#### Ethernet
|
||||
|
||||
```
|
||||
$ts eth $verb $ethertype $client_mac $masscanned_mac
|
||||
```
|
||||
|
||||
## To Do
|
||||
|
||||
|
|
|
@ -29,20 +29,18 @@ pub fn repl<'a, 'b>(
|
|||
arp_req: &'a ArpPacket,
|
||||
masscanned: &Masscanned,
|
||||
) -> Option<MutableArpPacket<'b>> {
|
||||
masscanned.log.arp_recv(arp_req);
|
||||
let mut arp_repl =
|
||||
MutableArpPacket::owned(arp_req.packet().to_vec()).expect("error parsing ARP packet");
|
||||
/* Build ARP answer depending of the type of request */
|
||||
match arp_req.get_operation() {
|
||||
ArpOperations::Request => {
|
||||
masscanned.log.arp_recv(arp_req);
|
||||
let ip = IpAddr::V4(arp_req.get_target_proto_addr());
|
||||
/* Ignore ARP requests for IP addresses not handled by masscanned */
|
||||
if let Some(ip_addr_list) = masscanned.ip_addresses {
|
||||
if !ip_addr_list.contains(&ip) {
|
||||
info!(
|
||||
"Ignoring ARP request from {} for IP {}",
|
||||
arp_req.get_sender_hw_addr(),
|
||||
ip
|
||||
);
|
||||
masscanned.log.arp_drop(arp_req);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
@ -53,17 +51,15 @@ pub fn repl<'a, 'b>(
|
|||
arp_repl.set_target_hw_addr(arp_req.get_sender_hw_addr().to_owned());
|
||||
arp_repl.set_target_proto_addr(arp_req.get_sender_proto_addr().to_owned());
|
||||
arp_repl.set_sender_proto_addr(arp_req.get_target_proto_addr().to_owned());
|
||||
warn!(
|
||||
"ARP-Reply to {} for IP {}",
|
||||
arp_req.get_sender_hw_addr(),
|
||||
arp_repl.get_sender_proto_addr()
|
||||
);
|
||||
masscanned.log.arp_send(&arp_repl);
|
||||
}
|
||||
_ => {
|
||||
info!("ARP Operation not handled: {:?}", arp_repl.get_operation());
|
||||
masscanned.log.arp_drop(arp_req);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
masscanned.log.arp_send(&arp_repl);
|
||||
Some(arp_repl)
|
||||
}
|
||||
|
||||
|
@ -76,6 +72,8 @@ mod tests {
|
|||
|
||||
use pnet::util::MacAddr;
|
||||
|
||||
use crate::logger::MetaLogger;
|
||||
|
||||
#[test]
|
||||
fn test_arp_reply() {
|
||||
let mut ips = HashSet::new();
|
||||
|
@ -86,6 +84,7 @@ mod tests {
|
|||
mac: MacAddr::from_str("00:11:22:33:44:55").expect("error parsing MAC address"),
|
||||
iface: None,
|
||||
ip_addresses: Some(&ips),
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
let mut arp_req =
|
||||
MutableArpPacket::owned([0; 28].to_vec()).expect("error constructing ARP request");
|
||||
|
|
|
@ -104,7 +104,10 @@ pub fn reply<'a, 'b>(
|
|||
masscanned: &Masscanned,
|
||||
mut client_info: &mut ClientInfo,
|
||||
) -> Option<MutableEthernetPacket<'b>> {
|
||||
debug!("receiving Ethernet packet: {:?}", eth_req);
|
||||
/* Fill client information for this packet with MAC addresses (src and dst) */
|
||||
client_info.mac.src = Some(eth_req.get_source());
|
||||
client_info.mac.dst = Some(eth_req.get_destination());
|
||||
masscanned.log.eth_recv(eth_req, &client_info);
|
||||
let mut eth_repl;
|
||||
/* First, check if the destination MAC address is one of those masscanned
|
||||
* is authorized to answer to (avoid answering to packets addressed to
|
||||
|
@ -113,16 +116,9 @@ pub fn reply<'a, 'b>(
|
|||
if !get_authorized_eth_addr(&masscanned.mac, masscanned.ip_addresses)
|
||||
.contains(ð_req.get_destination())
|
||||
{
|
||||
info!(
|
||||
"Ignoring Ethernet packet from {} to {}",
|
||||
eth_req.get_source(),
|
||||
eth_req.get_destination(),
|
||||
);
|
||||
masscanned.log.eth_drop(eth_req, &client_info);
|
||||
return None;
|
||||
}
|
||||
/* Fill client information for this packet with MAC addresses (src and dst) */
|
||||
client_info.mac.src = Some(eth_req.get_source());
|
||||
client_info.mac.dst = Some(eth_req.get_destination());
|
||||
/* Build next layer payload for answer depending on the incoming packet */
|
||||
match eth_req.get_ethertype() {
|
||||
/* Construct answer to ARP request */
|
||||
|
@ -136,6 +132,7 @@ pub fn reply<'a, 'b>(
|
|||
eth_repl.set_ethertype(EtherTypes::Arp);
|
||||
eth_repl.set_payload(arp_repl.packet());
|
||||
} else {
|
||||
masscanned.log.eth_drop(eth_req, &client_info);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
@ -145,6 +142,7 @@ pub fn reply<'a, 'b>(
|
|||
p
|
||||
} else {
|
||||
warn!("error parsing IPv4 packet");
|
||||
masscanned.log.eth_drop(eth_req, &client_info);
|
||||
return None;
|
||||
};
|
||||
if let Some(mut ipv4_repl) =
|
||||
|
@ -158,6 +156,7 @@ pub fn reply<'a, 'b>(
|
|||
eth_repl.set_ethertype(EtherTypes::Ipv4);
|
||||
eth_repl.set_payload(ipv4_repl.packet());
|
||||
} else {
|
||||
masscanned.log.eth_drop(eth_req, &client_info);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
@ -172,18 +171,20 @@ pub fn reply<'a, 'b>(
|
|||
eth_repl.set_ethertype(EtherTypes::Ipv6);
|
||||
eth_repl.set_payload(ipv6_repl.packet());
|
||||
} else {
|
||||
masscanned.log.eth_drop(eth_req, &client_info);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
/* Log & drop unknown network protocol */
|
||||
_ => {
|
||||
info!("Ethernet type not handled: {:?}", eth_req.get_ethertype());
|
||||
masscanned.log.eth_drop(eth_req, &client_info);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
eth_repl.set_source(masscanned.mac);
|
||||
eth_repl.set_destination(eth_req.get_source());
|
||||
debug!("sending Ethernet packet: {:?}", eth_repl);
|
||||
masscanned.log.eth_send(ð_repl, &client_info);
|
||||
Some(eth_repl)
|
||||
}
|
||||
|
||||
|
@ -193,6 +194,8 @@ mod tests {
|
|||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::logger::MetaLogger;
|
||||
|
||||
#[test]
|
||||
fn test_eth_reply() {
|
||||
/* test payload is IP(src="3.2.1.0", dst=".".join(str(b) for b in [0xaa, 0x99,
|
||||
|
@ -212,6 +215,7 @@ mod tests {
|
|||
mac: MacAddr::from_str("00:11:22:33:44:55").expect("error parsing MAC address"),
|
||||
iface: None,
|
||||
ip_addresses: Some(&ips),
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
let mut eth_req = MutableEthernetPacket::owned(vec![
|
||||
0;
|
||||
|
|
|
@ -39,24 +39,20 @@ pub fn repl<'a, 'b>(
|
|||
masscanned: &Masscanned,
|
||||
mut client_info: &mut ClientInfo,
|
||||
) -> Option<MutableIpv4Packet<'b>> {
|
||||
debug!("receiving IPv4 packet: {:?}", ip_req);
|
||||
/* Fill client info with source and dest. IP addresses */
|
||||
client_info.ip.src = Some(IpAddr::V4(ip_req.get_source()));
|
||||
client_info.ip.dst = Some(IpAddr::V4(ip_req.get_destination()));
|
||||
masscanned.log.ipv4_recv(&ip_req, &client_info);
|
||||
/* If masscanned is configured with IP addresses, then
|
||||
* check that the dest. IP address of the packet is one of
|
||||
* those handled by masscanned - otherwise, drop the packet.
|
||||
**/
|
||||
if let Some(ip_addr_list) = masscanned.ip_addresses {
|
||||
if !ip_addr_list.contains(&IpAddr::V4(ip_req.get_destination())) {
|
||||
info!(
|
||||
"Ignoring IP packet from {} for {}",
|
||||
ip_req.get_source(),
|
||||
ip_req.get_destination()
|
||||
);
|
||||
masscanned.log.ipv4_drop(&ip_req, &client_info);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
/* Fill client info with source and dest. IP addresses */
|
||||
client_info.ip.src = Some(IpAddr::V4(ip_req.get_source()));
|
||||
client_info.ip.dst = Some(IpAddr::V4(ip_req.get_destination()));
|
||||
/* Fill client info with transport layer procotol */
|
||||
client_info.transport = Some(ip_req.get_next_level_protocol());
|
||||
let mut ip_repl;
|
||||
|
@ -77,6 +73,7 @@ pub fn repl<'a, 'b>(
|
|||
ip_repl.set_payload(icmp_repl.packet());
|
||||
ip_repl.set_next_level_protocol(IpNextHeaderProtocols::Icmp);
|
||||
} else {
|
||||
masscanned.log.ipv4_drop(&ip_req, &client_info);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
@ -99,6 +96,7 @@ pub fn repl<'a, 'b>(
|
|||
ip_repl.set_payload(tcp_repl.packet());
|
||||
ip_repl.set_next_level_protocol(IpNextHeaderProtocols::Tcp);
|
||||
} else {
|
||||
masscanned.log.ipv4_drop(&ip_req, &client_info);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
@ -123,15 +121,13 @@ pub fn repl<'a, 'b>(
|
|||
ip_repl.set_payload(udp_repl.packet());
|
||||
ip_repl.set_next_level_protocol(IpNextHeaderProtocols::Udp);
|
||||
} else {
|
||||
masscanned.log.ipv4_drop(&ip_req, &client_info);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
/* Next layer protocol not handled (yet) - dropping packet */
|
||||
_ => {
|
||||
info!(
|
||||
"IPv4 upper layer not handled: {:?}",
|
||||
ip_req.get_next_level_protocol()
|
||||
);
|
||||
masscanned.log.ipv4_drop(&ip_req, &client_info);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
@ -150,7 +146,7 @@ pub fn repl<'a, 'b>(
|
|||
/* FIXME when dest. was a multicast IP address */
|
||||
ip_repl.set_source(ip_req.get_destination());
|
||||
ip_repl.set_destination(ip_req.get_source());
|
||||
debug!("sending IPv4 packet: {:?}", ip_repl);
|
||||
masscanned.log.ipv4_send(&ip_repl, &client_info);
|
||||
Some(ip_repl)
|
||||
}
|
||||
|
||||
|
@ -163,6 +159,8 @@ mod tests {
|
|||
|
||||
use pnet::util::MacAddr;
|
||||
|
||||
use crate::logger::MetaLogger;
|
||||
|
||||
#[test]
|
||||
fn test_ipv4_reply() {
|
||||
/* test payload is scapy> ICMP() */
|
||||
|
@ -178,6 +176,7 @@ mod tests {
|
|||
mac: MacAddr::from_str("00:11:22:33:44:55").expect("error parsing MAC address"),
|
||||
iface: None,
|
||||
ip_addresses: Some(&ips),
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
let mut ip_req =
|
||||
MutableIpv4Packet::owned(vec![0; Ipv4Packet::minimum_packet_size() + payload.len()])
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with Masscanned. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use log::*;
|
||||
use std::net::IpAddr;
|
||||
|
||||
use pnet::packet::{
|
||||
|
@ -35,7 +34,10 @@ pub fn repl<'a, 'b>(
|
|||
masscanned: &Masscanned,
|
||||
mut client_info: &mut ClientInfo,
|
||||
) -> Option<MutableIpv6Packet<'b>> {
|
||||
debug!("receiving IPv6 packet: {:?}", ip_req);
|
||||
/* Fill client info with source and dest. IP address */
|
||||
client_info.ip.src = Some(IpAddr::V6(ip_req.get_source()));
|
||||
client_info.ip.dst = Some(IpAddr::V6(ip_req.get_destination()));
|
||||
masscanned.log.ipv6_recv(ip_req, client_info);
|
||||
let src = ip_req.get_source();
|
||||
let mut dst = ip_req.get_destination();
|
||||
/* If masscanned is configured with IP addresses, check that
|
||||
|
@ -46,7 +48,7 @@ pub fn repl<'a, 'b>(
|
|||
if !ip_addr_list.contains(&IpAddr::V6(dst))
|
||||
&& ip_req.get_next_header() != IpNextHeaderProtocols::Icmpv6
|
||||
{
|
||||
info!("Ignoring IP packet from {} for {}", &src, &dst);
|
||||
masscanned.log.ipv6_drop(ip_req, client_info);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
@ -84,6 +86,7 @@ pub fn repl<'a, 'b>(
|
|||
ip_repl.set_hop_limit(255);
|
||||
};
|
||||
} else {
|
||||
masscanned.log.ipv6_drop(ip_req, client_info);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
@ -108,6 +111,7 @@ pub fn repl<'a, 'b>(
|
|||
ip_repl.set_payload_length(tcp_len as u16);
|
||||
ip_repl.set_payload(&tcp_repl.packet());
|
||||
} else {
|
||||
masscanned.log.ipv6_drop(ip_req, client_info);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
@ -132,15 +136,13 @@ pub fn repl<'a, 'b>(
|
|||
ip_repl.set_payload_length(udp_len as u16);
|
||||
ip_repl.set_payload(&udp_repl.packet());
|
||||
} else {
|
||||
masscanned.log.ipv6_drop(ip_req, client_info);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
/* Other protocols are not handled (yet) - dropping */
|
||||
_ => {
|
||||
info!(
|
||||
"IPv6 upper layer not handled: {:?}",
|
||||
ip_req.get_next_header()
|
||||
);
|
||||
masscanned.log.ipv6_drop(ip_req, client_info);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
@ -153,7 +155,7 @@ pub fn repl<'a, 'b>(
|
|||
/* Set packet source and dest. */
|
||||
ip_repl.set_source(dst);
|
||||
ip_repl.set_destination(src);
|
||||
debug!("sending IPv6 packet: {:?}", ip_repl);
|
||||
masscanned.log.ipv6_send(&ip_repl, client_info);
|
||||
Some(ip_repl)
|
||||
}
|
||||
|
||||
|
@ -166,6 +168,8 @@ mod tests {
|
|||
|
||||
use pnet::util::MacAddr;
|
||||
|
||||
use crate::logger::MetaLogger;
|
||||
|
||||
#[test]
|
||||
fn test_ipv6_reply() {
|
||||
/* test payload is scapy> IPv6(src="7777:6666:5555:4444:3333:2222:1111:0000",
|
||||
|
@ -187,6 +191,7 @@ mod tests {
|
|||
mac: MacAddr::from_str("00:11:22:33:44:55").expect("error parsing MAC address"),
|
||||
iface: None,
|
||||
ip_addresses: Some(&ips),
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
let mut ip_req =
|
||||
MutableIpv6Packet::owned(vec![0; Ipv6Packet::minimum_packet_size() + payload.len()])
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with Masscanned. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use log::*;
|
||||
|
||||
use pnet::packet::{
|
||||
icmp::{IcmpCode, IcmpPacket, IcmpTypes, MutableIcmpPacket},
|
||||
Packet,
|
||||
|
@ -26,16 +24,16 @@ use crate::Masscanned;
|
|||
|
||||
pub fn repl<'a, 'b>(
|
||||
icmp_req: &'a IcmpPacket,
|
||||
_masscanned: &Masscanned,
|
||||
mut _client_info: &ClientInfo,
|
||||
masscanned: &Masscanned,
|
||||
client_info: &ClientInfo,
|
||||
) -> Option<MutableIcmpPacket<'b>> {
|
||||
debug!("receiving ICMPv4 packet: {:?}", icmp_req);
|
||||
masscanned.log.icmpv4_recv(icmp_req, client_info);
|
||||
let mut icmp_repl;
|
||||
match icmp_req.get_icmp_type() {
|
||||
IcmpTypes::EchoRequest => {
|
||||
/* Check code of ICMP packet */
|
||||
if icmp_req.get_icmp_code() != IcmpCode(0) {
|
||||
info!("ICMP code not handled: {:?}", icmp_req.get_icmp_code());
|
||||
masscanned.log.icmpv4_drop(icmp_req, client_info);
|
||||
return None;
|
||||
}
|
||||
/* Compute answer length */
|
||||
|
@ -53,13 +51,13 @@ pub fn repl<'a, 'b>(
|
|||
* reply message."
|
||||
**/
|
||||
icmp_repl.set_payload(icmp_req.payload());
|
||||
warn!("ICMP-Echo-Reply to ICMP-Echo-Request");
|
||||
}
|
||||
_ => {
|
||||
masscanned.log.icmpv4_drop(icmp_req, client_info);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
debug!("sending ICMPv4 packet: {:?}", icmp_repl);
|
||||
masscanned.log.icmpv4_send(&icmp_repl, client_info);
|
||||
Some(icmp_repl)
|
||||
}
|
||||
|
||||
|
@ -70,6 +68,8 @@ mod tests {
|
|||
|
||||
use pnet::util::MacAddr;
|
||||
|
||||
use crate::logger::MetaLogger;
|
||||
|
||||
#[test]
|
||||
fn test_icmpv4_reply() {
|
||||
/* test payload is scapy> ICMP() */
|
||||
|
@ -81,6 +81,7 @@ mod tests {
|
|||
mac: MacAddr::from_str("00:11:22:33:44:55").expect("error parsing MAC address"),
|
||||
iface: None,
|
||||
ip_addresses: None,
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
let mut icmp_req =
|
||||
MutableIcmpPacket::owned(vec![0; IcmpPacket::minimum_packet_size() + payload.len()])
|
||||
|
|
|
@ -103,7 +103,7 @@ pub fn repl<'a, 'b>(
|
|||
masscanned: &Masscanned,
|
||||
client_info: &ClientInfo,
|
||||
) -> (Option<MutableIcmpv6Packet<'b>>, Option<Ipv6Addr>) {
|
||||
debug!("receiving ICMPv6 packet: {:?}", icmp_req);
|
||||
masscanned.log.icmpv6_recv(icmp_req, client_info);
|
||||
let mut dst_ip = None;
|
||||
if icmp_req.get_icmpv6_code() != Icmpv6Codes::NoCode {
|
||||
return (None, None);
|
||||
|
@ -120,6 +120,7 @@ pub fn repl<'a, 'b>(
|
|||
icmp_repl = MutableIcmpv6Packet::owned(nd_na_repl.packet().to_vec())
|
||||
.expect("error constructing an ICMPv6 packet");
|
||||
} else {
|
||||
masscanned.log.icmpv6_drop(icmp_req, client_info);
|
||||
return (None, None);
|
||||
}
|
||||
}
|
||||
|
@ -136,17 +137,13 @@ pub fn repl<'a, 'b>(
|
|||
icmp_repl = MutableIcmpv6Packet::owned(vec![0; Icmpv6Packet::packet_size(&echo_repl)])
|
||||
.expect("error constructing an ICMPv6 packet");
|
||||
icmp_repl.populate(&echo_repl);
|
||||
warn!("ICMPv6-Echo-Reply to ICMPv6-Echo-Request");
|
||||
}
|
||||
_ => {
|
||||
info!(
|
||||
"ICMPv6 packet not handled: {:?}",
|
||||
icmp_req.get_icmpv6_type()
|
||||
);
|
||||
masscanned.log.icmpv6_drop(icmp_req, client_info);
|
||||
return (None, None);
|
||||
}
|
||||
};
|
||||
debug!("sending ICMPv6 packet: {:?}", icmp_repl);
|
||||
masscanned.log.icmpv6_send(&icmp_repl, client_info);
|
||||
(Some(icmp_repl), dst_ip)
|
||||
}
|
||||
|
||||
|
@ -160,6 +157,8 @@ mod tests {
|
|||
use pnet::packet::icmpv6::ndp::{MutableNeighborSolicitPacket, NeighborSolicit};
|
||||
use pnet::util::MacAddr;
|
||||
|
||||
use crate::logger::MetaLogger;
|
||||
|
||||
#[test]
|
||||
fn test_nd_na_reply() {
|
||||
let client_info = ClientInfo::new();
|
||||
|
@ -174,6 +173,7 @@ mod tests {
|
|||
mac: MacAddr::from_str("00:11:22:33:44:55").expect("error parsing MAC address"),
|
||||
iface: None,
|
||||
ip_addresses: Some(&ips),
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
/* Legitimate solicitation */
|
||||
let ndp_ns = NeighborSolicit {
|
||||
|
@ -246,6 +246,7 @@ mod tests {
|
|||
mac: MacAddr::from_str("00:11:22:33:44:55").expect("error parsing MAC address"),
|
||||
iface: None,
|
||||
ip_addresses: Some(&ips),
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
let mut icmpv6_echo_req = MutableIcmpv6Packet::owned(vec![
|
||||
0;
|
||||
|
|
|
@ -31,7 +31,7 @@ pub fn repl<'a, 'b>(
|
|||
masscanned: &Masscanned,
|
||||
mut client_info: &mut ClientInfo,
|
||||
) -> Option<MutableTcpPacket<'b>> {
|
||||
debug!("receiving TCP packet: {:?}", tcp_req);
|
||||
masscanned.log.tcp_recv(tcp_req, client_info);
|
||||
/* Fill client info with source and dest. TCP port */
|
||||
client_info.port.src = Some(tcp_req.get_source());
|
||||
client_info.port.dst = Some(tcp_req.get_destination());
|
||||
|
@ -50,7 +50,7 @@ pub fn repl<'a, 'b>(
|
|||
/* Compute syncookie */
|
||||
if let Ok(cookie) = synackcookie::generate(&client_info, &masscanned.synack_key) {
|
||||
if cookie != ackno {
|
||||
info!("PSH-ACK ignored: synackcookie not valid");
|
||||
masscanned.log.tcp_drop(tcp_req, client_info);
|
||||
return None;
|
||||
}
|
||||
client_info.cookie = Some(cookie);
|
||||
|
@ -76,10 +76,12 @@ pub fn repl<'a, 'b>(
|
|||
/* Answer to ACK: nothing */
|
||||
flags if flags == TcpFlags::ACK => {
|
||||
/* answer here when server needs to speak first after handshake */
|
||||
masscanned.log.tcp_drop(tcp_req, client_info);
|
||||
return None;
|
||||
}
|
||||
/* Answer to RST: nothing */
|
||||
flags if flags == TcpFlags::RST => {
|
||||
masscanned.log.tcp_drop(tcp_req, client_info);
|
||||
return None;
|
||||
}
|
||||
/* Answer to FIN,ACK with FIN,ACK */
|
||||
|
@ -101,10 +103,9 @@ pub fn repl<'a, 'b>(
|
|||
tcp_repl.set_sequence(
|
||||
synackcookie::generate(&client_info, &masscanned.synack_key).unwrap(),
|
||||
);
|
||||
warn!("SYN-ACK to ACK on port {}", tcp_req.get_destination());
|
||||
}
|
||||
_ => {
|
||||
info!("TCP flag not handled: {}", tcp_req.get_flags());
|
||||
masscanned.log.tcp_drop(tcp_req, client_info);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +116,7 @@ pub fn repl<'a, 'b>(
|
|||
/* Set TCP headers */
|
||||
tcp_repl.set_data_offset(5);
|
||||
tcp_repl.set_window(65535);
|
||||
debug!("sending TCP packet: {:?}", tcp_repl);
|
||||
masscanned.log.tcp_send(&tcp_repl, client_info);
|
||||
Some(tcp_repl)
|
||||
}
|
||||
|
||||
|
@ -126,6 +127,8 @@ mod tests {
|
|||
use pnet::util::MacAddr;
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
|
||||
use crate::logger::MetaLogger;
|
||||
|
||||
#[test]
|
||||
fn test_tcp_fin_ack() {
|
||||
let masscanned = Masscanned {
|
||||
|
@ -133,6 +136,7 @@ mod tests {
|
|||
ip_addresses: None,
|
||||
synack_key: [0x06a0a1d63f305e9b, 0xd4d4bcbb7304875f],
|
||||
iface: None,
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
/* reference */
|
||||
let ip_src = IpAddr::V4(Ipv4Addr::new(27, 198, 143, 1));
|
||||
|
@ -183,6 +187,7 @@ mod tests {
|
|||
ip_addresses: None,
|
||||
synack_key: [0x06a0a1d63f305e9b, 0xd4d4bcbb7304875f],
|
||||
iface: None,
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
/* reference */
|
||||
let ip_src = IpAddr::V4(Ipv4Addr::new(27, 198, 143, 1));
|
||||
|
@ -232,6 +237,7 @@ mod tests {
|
|||
ip_addresses: None,
|
||||
synack_key: [0x06a0a1d63f305e9b, 0xd4d4bcbb7304875f],
|
||||
iface: None,
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
/* reference */
|
||||
let ip_src = IpAddr::V6(Ipv6Addr::new(234, 52, 183, 47, 184, 172, 64, 141));
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with Masscanned. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use log::*;
|
||||
|
||||
use pnet::packet::{
|
||||
udp::{MutableUdpPacket, UdpPacket},
|
||||
Packet,
|
||||
|
@ -30,7 +28,7 @@ pub fn repl<'a, 'b>(
|
|||
masscanned: &Masscanned,
|
||||
mut client_info: &mut ClientInfo,
|
||||
) -> Option<MutableUdpPacket<'b>> {
|
||||
debug!("receiving UDP packet: {:?}", udp_req);
|
||||
masscanned.log.udp_recv(udp_req, client_info);
|
||||
/* Fill client info with source and dest. UDP port */
|
||||
client_info.port.src = Some(udp_req.get_source());
|
||||
client_info.port.dst = Some(udp_req.get_destination());
|
||||
|
@ -43,12 +41,13 @@ pub fn repl<'a, 'b>(
|
|||
.expect("error constructing a UDP packet");
|
||||
udp_repl.set_length(udp_repl.packet().len() as u16);
|
||||
} else {
|
||||
masscanned.log.udp_drop(udp_req, client_info);
|
||||
return None;
|
||||
}
|
||||
/* Set source and dest. port for response packet from client info */
|
||||
/* Note: client info could have been modified by upper layers (e.g., STUN) */
|
||||
udp_repl.set_source(client_info.port.dst.unwrap());
|
||||
udp_repl.set_destination(client_info.port.src.unwrap());
|
||||
debug!("sending UDP packet: {:?}", udp_repl);
|
||||
masscanned.log.udp_send(&udp_repl, client_info);
|
||||
Some(udp_repl)
|
||||
}
|
||||
|
|
308
src/logger/console.rs
Normal file
308
src/logger/console.rs
Normal file
|
@ -0,0 +1,308 @@
|
|||
// This file is part of masscanned.
|
||||
// Copyright 2021 - The IVRE project
|
||||
//
|
||||
// Masscanned is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Masscanned is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Masscanned. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::time::SystemTime;
|
||||
|
||||
use pnet::packet::{
|
||||
arp::{ArpPacket, MutableArpPacket},
|
||||
ethernet::{EthernetPacket, MutableEthernetPacket},
|
||||
icmp::{IcmpPacket, MutableIcmpPacket},
|
||||
icmpv6::{Icmpv6Packet, MutableIcmpv6Packet},
|
||||
ipv4::{Ipv4Packet, MutableIpv4Packet},
|
||||
ipv6::{Ipv6Packet, MutableIpv6Packet},
|
||||
tcp::{MutableTcpPacket, TcpPacket},
|
||||
udp::{MutableUdpPacket, UdpPacket},
|
||||
};
|
||||
|
||||
use crate::client::ClientInfo;
|
||||
use crate::logger::Logger;
|
||||
|
||||
pub struct ConsoleLogger {
|
||||
arp: bool,
|
||||
eth: bool,
|
||||
ipv4: bool,
|
||||
ipv6: bool,
|
||||
icmpv4: bool,
|
||||
icmpv6: bool,
|
||||
tcp: bool,
|
||||
udp: bool,
|
||||
}
|
||||
|
||||
impl ConsoleLogger {
|
||||
pub fn new() -> Self {
|
||||
ConsoleLogger {
|
||||
arp: true,
|
||||
eth: true,
|
||||
ipv4: true,
|
||||
ipv6: true,
|
||||
icmpv4: true,
|
||||
icmpv6: true,
|
||||
tcp: true,
|
||||
udp: true,
|
||||
}
|
||||
}
|
||||
fn prolog(&self, proto: &str, verb: &str, crlf: bool) {
|
||||
let now = SystemTime::now()
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.unwrap();
|
||||
print!(
|
||||
"{}.{}\t{}\t{}{}",
|
||||
now.as_secs(),
|
||||
now.subsec_millis(),
|
||||
proto,
|
||||
verb,
|
||||
if crlf { "\n" } else { "\t" },
|
||||
);
|
||||
}
|
||||
fn client_info(&self, c: &ClientInfo) {
|
||||
print!(
|
||||
"{}\t{}\t{}\t{}\t{}\t{}\t{}\t",
|
||||
if let Some(m) = c.mac.src {
|
||||
format!("{}", m)
|
||||
} else {
|
||||
"".to_string()
|
||||
},
|
||||
if let Some(m) = c.mac.dst {
|
||||
format!("{}", m)
|
||||
} else {
|
||||
"".to_string()
|
||||
},
|
||||
if let Some(i) = c.ip.src {
|
||||
format!("{}", i)
|
||||
} else {
|
||||
"".to_string()
|
||||
},
|
||||
if let Some(i) = c.ip.dst {
|
||||
format!("{}", i)
|
||||
} else {
|
||||
"".to_string()
|
||||
},
|
||||
if let Some(t) = c.transport {
|
||||
format!("{}", t)
|
||||
} else {
|
||||
"".to_string()
|
||||
},
|
||||
if let Some(p) = c.port.src {
|
||||
format!("{}", p)
|
||||
} else {
|
||||
"".to_string()
|
||||
},
|
||||
if let Some(p) = c.port.dst {
|
||||
format!("{}", p)
|
||||
} else {
|
||||
"".to_string()
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
impl Logger for ConsoleLogger {
|
||||
fn init(&self) {
|
||||
self.prolog("arp", "init", true);
|
||||
self.prolog("eth", "init", true);
|
||||
self.prolog("ipv4", "init", true);
|
||||
self.prolog("ipv6", "init", true);
|
||||
self.prolog("icmpv4", "init", true);
|
||||
self.prolog("icmpv6", "init", true);
|
||||
self.prolog("tcp", "init", true);
|
||||
self.prolog("udp", "init", true);
|
||||
}
|
||||
/* ARP */
|
||||
fn arp_enabled(&self) -> bool {
|
||||
self.arp
|
||||
}
|
||||
fn arp_recv(&self, p: &ArpPacket) {
|
||||
self.prolog("arp", "recv", false);
|
||||
println!(
|
||||
"{:}\t{:}\t{:}\t{:}\t{:?}",
|
||||
p.get_sender_hw_addr(),
|
||||
p.get_target_hw_addr(),
|
||||
p.get_sender_proto_addr(),
|
||||
p.get_target_proto_addr(),
|
||||
p.get_operation(),
|
||||
);
|
||||
}
|
||||
fn arp_drop(&self, p: &ArpPacket) {
|
||||
self.prolog("arp", "drop", false);
|
||||
println!(
|
||||
"{:}\t{:}\t{:}\t{:}\t{:?}",
|
||||
p.get_sender_hw_addr(),
|
||||
p.get_target_hw_addr(),
|
||||
p.get_sender_proto_addr(),
|
||||
p.get_target_proto_addr(),
|
||||
p.get_operation(),
|
||||
);
|
||||
}
|
||||
fn arp_send(&self, p: &MutableArpPacket) {
|
||||
self.prolog("arp", "send", false);
|
||||
println!(
|
||||
"{:}\t{:}\t{:}\t{:}\t{:?}",
|
||||
p.get_target_hw_addr(),
|
||||
p.get_sender_hw_addr(),
|
||||
p.get_target_proto_addr(),
|
||||
p.get_sender_proto_addr(),
|
||||
p.get_operation(),
|
||||
);
|
||||
}
|
||||
/* Ethernet */
|
||||
fn eth_enabled(&self) -> bool {
|
||||
self.eth
|
||||
}
|
||||
fn eth_recv(&self, p: &EthernetPacket, c: &ClientInfo) {
|
||||
self.prolog("eth", "recv", false);
|
||||
self.client_info(c);
|
||||
println!("{:}", p.get_ethertype(),);
|
||||
}
|
||||
fn eth_drop(&self, p: &EthernetPacket, c: &ClientInfo) {
|
||||
self.prolog("eth", "drop", false);
|
||||
self.client_info(c);
|
||||
println!("{:}", p.get_ethertype(),);
|
||||
}
|
||||
fn eth_send(&self, p: &MutableEthernetPacket, c: &ClientInfo) {
|
||||
self.prolog("eth", "send", false);
|
||||
self.client_info(c);
|
||||
println!("{:}", p.get_ethertype(),);
|
||||
}
|
||||
/* IPv4 */
|
||||
fn ipv4_enabled(&self) -> bool {
|
||||
self.ipv4
|
||||
}
|
||||
fn ipv4_recv(&self, p: &Ipv4Packet, c: &ClientInfo) {
|
||||
self.prolog("ipv4", "recv", false);
|
||||
self.client_info(c);
|
||||
println!("{:}", p.get_next_level_protocol(),);
|
||||
}
|
||||
fn ipv4_drop(&self, p: &Ipv4Packet, c: &ClientInfo) {
|
||||
self.prolog("ipv4", "drop", false);
|
||||
self.client_info(c);
|
||||
println!("{:}", p.get_next_level_protocol(),);
|
||||
}
|
||||
fn ipv4_send(&self, p: &MutableIpv4Packet, c: &ClientInfo) {
|
||||
self.prolog("ipv4", "send", false);
|
||||
self.client_info(c);
|
||||
println!("{:}", p.get_next_level_protocol(),);
|
||||
}
|
||||
/* IPv6 */
|
||||
fn ipv6_enabled(&self) -> bool {
|
||||
self.ipv6
|
||||
}
|
||||
fn ipv6_recv(&self, p: &Ipv6Packet, c: &ClientInfo) {
|
||||
self.prolog("ipv6", "recv", false);
|
||||
self.client_info(c);
|
||||
println!("{:}", p.get_next_header(),);
|
||||
}
|
||||
fn ipv6_drop(&self, p: &Ipv6Packet, c: &ClientInfo) {
|
||||
self.prolog("ipv6", "drop", false);
|
||||
self.client_info(c);
|
||||
println!("{:}", p.get_next_header(),);
|
||||
}
|
||||
fn ipv6_send(&self, p: &MutableIpv6Packet, c: &ClientInfo) {
|
||||
self.prolog("ipv6", "send", false);
|
||||
self.client_info(c);
|
||||
println!("{:}", p.get_next_header(),);
|
||||
}
|
||||
/* ICMPv4 */
|
||||
fn icmpv4_enabled(&self) -> bool {
|
||||
self.icmpv4
|
||||
}
|
||||
fn icmpv4_recv(&self, p: &IcmpPacket, c: &ClientInfo) {
|
||||
self.prolog("icmpv4", "recv", false);
|
||||
self.client_info(c);
|
||||
println!("{:?}\t{:?}", p.get_icmp_type(), p.get_icmp_code(),);
|
||||
}
|
||||
fn icmpv4_drop(&self, p: &IcmpPacket, c: &ClientInfo) {
|
||||
self.prolog("icmpv4", "drop", false);
|
||||
self.client_info(c);
|
||||
println!("{:?}\t{:?}", p.get_icmp_type(), p.get_icmp_code(),);
|
||||
}
|
||||
fn icmpv4_send(&self, p: &MutableIcmpPacket, c: &ClientInfo) {
|
||||
self.prolog("icmpv4", "send", false);
|
||||
self.client_info(c);
|
||||
println!("{:?}\t{:?}", p.get_icmp_type(), p.get_icmp_code(),);
|
||||
}
|
||||
/* ICMPv6 */
|
||||
fn icmpv6_enabled(&self) -> bool {
|
||||
self.icmpv6
|
||||
}
|
||||
fn icmpv6_recv(&self, p: &Icmpv6Packet, c: &ClientInfo) {
|
||||
self.prolog("icmpv6", "recv", false);
|
||||
self.client_info(c);
|
||||
println!("{:?}\t{:?}", p.get_icmpv6_type(), p.get_icmpv6_code(),);
|
||||
}
|
||||
fn icmpv6_drop(&self, p: &Icmpv6Packet, c: &ClientInfo) {
|
||||
self.prolog("icmpv6", "drop", false);
|
||||
self.client_info(c);
|
||||
println!("{:?}\t{:?}", p.get_icmpv6_type(), p.get_icmpv6_code(),);
|
||||
}
|
||||
fn icmpv6_send(&self, p: &MutableIcmpv6Packet, c: &ClientInfo) {
|
||||
self.prolog("icmpv6", "send", false);
|
||||
self.client_info(c);
|
||||
println!("{:?}\t{:?}", p.get_icmpv6_type(), p.get_icmpv6_code(),);
|
||||
}
|
||||
/* TCP */
|
||||
fn tcp_enabled(&self) -> bool {
|
||||
self.tcp
|
||||
}
|
||||
fn tcp_recv(&self, p: &TcpPacket, c: &ClientInfo) {
|
||||
self.prolog("tcp", "recv", false);
|
||||
self.client_info(c);
|
||||
println!(
|
||||
"{:?}\t{:}\t{:}",
|
||||
p.get_flags(),
|
||||
p.get_sequence(),
|
||||
p.get_acknowledgement(),
|
||||
);
|
||||
}
|
||||
fn tcp_drop(&self, p: &TcpPacket, c: &ClientInfo) {
|
||||
self.prolog("tcp", "drop", false);
|
||||
self.client_info(c);
|
||||
println!(
|
||||
"{:?}\t{:}\t{:}",
|
||||
p.get_flags(),
|
||||
p.get_sequence(),
|
||||
p.get_acknowledgement(),
|
||||
);
|
||||
}
|
||||
fn tcp_send(&self, p: &MutableTcpPacket, c: &ClientInfo) {
|
||||
self.prolog("tcp", "send", false);
|
||||
self.client_info(c);
|
||||
println!(
|
||||
"{:?}\t{:}\t{:}",
|
||||
p.get_flags(),
|
||||
p.get_sequence(),
|
||||
p.get_acknowledgement(),
|
||||
);
|
||||
}
|
||||
/* UDP */
|
||||
fn udp_enabled(&self) -> bool {
|
||||
self.udp
|
||||
}
|
||||
fn udp_recv(&self, _p: &UdpPacket, c: &ClientInfo) {
|
||||
self.prolog("udp", "recv", false);
|
||||
self.client_info(c);
|
||||
println!("");
|
||||
}
|
||||
fn udp_drop(&self, _p: &UdpPacket, c: &ClientInfo) {
|
||||
self.prolog("udp", "drop", false);
|
||||
self.client_info(c);
|
||||
println!("");
|
||||
}
|
||||
fn udp_send(&self, _p: &MutableUdpPacket, c: &ClientInfo) {
|
||||
self.prolog("udp", "send", false);
|
||||
self.client_info(c);
|
||||
println!("");
|
||||
}
|
||||
}
|
225
src/logger/meta.rs
Normal file
225
src/logger/meta.rs
Normal file
|
@ -0,0 +1,225 @@
|
|||
// This file is part of masscanned.
|
||||
// Copyright 2021 - The IVRE project
|
||||
//
|
||||
// Masscanned is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Masscanned is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Masscanned. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use pnet::packet::{
|
||||
arp::{ArpPacket, MutableArpPacket},
|
||||
ethernet::{EthernetPacket, MutableEthernetPacket},
|
||||
icmp::{IcmpPacket, MutableIcmpPacket},
|
||||
icmpv6::{Icmpv6Packet, MutableIcmpv6Packet},
|
||||
ipv4::{Ipv4Packet, MutableIpv4Packet},
|
||||
ipv6::{Ipv6Packet, MutableIpv6Packet},
|
||||
tcp::{MutableTcpPacket, TcpPacket},
|
||||
udp::{MutableUdpPacket, UdpPacket},
|
||||
};
|
||||
|
||||
use crate::client::ClientInfo;
|
||||
use crate::logger::Logger;
|
||||
|
||||
pub struct MetaLogger {
|
||||
loggers: Vec<Box<dyn Logger>>,
|
||||
}
|
||||
|
||||
impl MetaLogger {
|
||||
pub fn new() -> Self {
|
||||
MetaLogger {
|
||||
loggers: Vec::new(),
|
||||
}
|
||||
}
|
||||
pub fn add(&mut self, log: Box<dyn Logger>) {
|
||||
self.loggers.push(log);
|
||||
}
|
||||
pub fn init(&self) {
|
||||
for l in &self.loggers {
|
||||
l.init();
|
||||
}
|
||||
}
|
||||
/* ARP */
|
||||
pub fn arp_recv(&self, p: &ArpPacket) {
|
||||
for l in &self.loggers {
|
||||
if l.arp_enabled() {
|
||||
l.arp_recv(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn arp_drop(&self, p: &ArpPacket) {
|
||||
for l in &self.loggers {
|
||||
if l.arp_enabled() {
|
||||
l.arp_drop(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn arp_send(&self, p: &MutableArpPacket) {
|
||||
for l in &self.loggers {
|
||||
if l.arp_enabled() {
|
||||
l.arp_send(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Ethernet */
|
||||
pub fn eth_recv(&self, p: &EthernetPacket, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.eth_enabled() {
|
||||
l.eth_recv(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn eth_drop(&self, p: &EthernetPacket, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.eth_enabled() {
|
||||
l.eth_drop(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn eth_send(&self, p: &MutableEthernetPacket, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.eth_enabled() {
|
||||
l.eth_send(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* IPv4 */
|
||||
pub fn ipv4_recv(&self, p: &Ipv4Packet, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.ipv4_enabled() {
|
||||
l.ipv4_recv(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn ipv4_drop(&self, p: &Ipv4Packet, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.ipv4_enabled() {
|
||||
l.ipv4_drop(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn ipv4_send(&self, p: &MutableIpv4Packet, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.ipv4_enabled() {
|
||||
l.ipv4_send(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* IPv6 */
|
||||
pub fn ipv6_recv(&self, p: &Ipv6Packet, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.ipv6_enabled() {
|
||||
l.ipv6_recv(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn ipv6_drop(&self, p: &Ipv6Packet, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.ipv6_enabled() {
|
||||
l.ipv6_drop(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn ipv6_send(&self, p: &MutableIpv6Packet, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.ipv6_enabled() {
|
||||
l.ipv6_send(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* ICMPv4 */
|
||||
pub fn icmpv4_recv(&self, p: &IcmpPacket, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.icmpv4_enabled() {
|
||||
l.icmpv4_recv(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn icmpv4_drop(&self, p: &IcmpPacket, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.icmpv4_enabled() {
|
||||
l.icmpv4_drop(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn icmpv4_send(&self, p: &MutableIcmpPacket, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.icmpv4_enabled() {
|
||||
l.icmpv4_send(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* ICMPv6 */
|
||||
pub fn icmpv6_recv(&self, p: &Icmpv6Packet, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.icmpv6_enabled() {
|
||||
l.icmpv6_recv(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn icmpv6_drop(&self, p: &Icmpv6Packet, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.icmpv6_enabled() {
|
||||
l.icmpv6_drop(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn icmpv6_send(&self, p: &MutableIcmpv6Packet, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.icmpv6_enabled() {
|
||||
l.icmpv6_send(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* TCP */
|
||||
pub fn tcp_recv(&self, p: &TcpPacket, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.tcp_enabled() {
|
||||
l.tcp_recv(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn tcp_drop(&self, p: &TcpPacket, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.tcp_enabled() {
|
||||
l.tcp_drop(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn tcp_send(&self, p: &MutableTcpPacket, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.tcp_enabled() {
|
||||
l.tcp_send(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* UDP */
|
||||
pub fn udp_recv(&self, p: &UdpPacket, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.udp_enabled() {
|
||||
l.udp_recv(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn udp_drop(&self, p: &UdpPacket, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.udp_enabled() {
|
||||
l.udp_drop(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn udp_send(&self, p: &MutableUdpPacket, c: &ClientInfo) {
|
||||
for l in &self.loggers {
|
||||
if l.udp_enabled() {
|
||||
l.udp_send(p, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
95
src/logger/mod.rs
Normal file
95
src/logger/mod.rs
Normal file
|
@ -0,0 +1,95 @@
|
|||
// This file is part of masscanned.
|
||||
// Copyright 2021 - The IVRE project
|
||||
//
|
||||
// Masscanned is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Masscanned is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Masscanned. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use pnet::packet::{
|
||||
arp::{ArpPacket, MutableArpPacket},
|
||||
ethernet::{EthernetPacket, MutableEthernetPacket},
|
||||
icmp::{IcmpPacket, MutableIcmpPacket},
|
||||
icmpv6::{Icmpv6Packet, MutableIcmpv6Packet},
|
||||
ipv4::{Ipv4Packet, MutableIpv4Packet},
|
||||
ipv6::{Ipv6Packet, MutableIpv6Packet},
|
||||
tcp::{MutableTcpPacket, TcpPacket},
|
||||
udp::{MutableUdpPacket, UdpPacket},
|
||||
};
|
||||
|
||||
use crate::client::ClientInfo;
|
||||
|
||||
mod console;
|
||||
mod meta;
|
||||
|
||||
pub use console::ConsoleLogger;
|
||||
pub use meta::MetaLogger;
|
||||
|
||||
pub trait Logger {
|
||||
fn init(&self);
|
||||
/* list of notifications that a logger might or might not implement */
|
||||
/* ARP */
|
||||
fn arp_enabled(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn arp_recv(&self, _p: &ArpPacket) {}
|
||||
fn arp_drop(&self, _p: &ArpPacket) {}
|
||||
fn arp_send(&self, _p: &MutableArpPacket) {}
|
||||
/* Ethernet */
|
||||
fn eth_enabled(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn eth_recv(&self, _p: &EthernetPacket, _c: &ClientInfo) {}
|
||||
fn eth_drop(&self, _p: &EthernetPacket, _c: &ClientInfo) {}
|
||||
fn eth_send(&self, _p: &MutableEthernetPacket, _c: &ClientInfo) {}
|
||||
/* IPv4 */
|
||||
fn ipv4_enabled(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn ipv4_recv(&self, _p: &Ipv4Packet, _c: &ClientInfo) {}
|
||||
fn ipv4_drop(&self, _p: &Ipv4Packet, _c: &ClientInfo) {}
|
||||
fn ipv4_send(&self, _p: &MutableIpv4Packet, _c: &ClientInfo) {}
|
||||
/* IPv6 */
|
||||
fn ipv6_enabled(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn ipv6_recv(&self, _p: &Ipv6Packet, _c: &ClientInfo) {}
|
||||
fn ipv6_drop(&self, _p: &Ipv6Packet, _c: &ClientInfo) {}
|
||||
fn ipv6_send(&self, _p: &MutableIpv6Packet, _c: &ClientInfo) {}
|
||||
/* ICMPv4 */
|
||||
fn icmpv4_enabled(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn icmpv4_recv(&self, _p: &IcmpPacket, _c: &ClientInfo) {}
|
||||
fn icmpv4_drop(&self, _p: &IcmpPacket, _c: &ClientInfo) {}
|
||||
fn icmpv4_send(&self, _p: &MutableIcmpPacket, _c: &ClientInfo) {}
|
||||
/* ICMPv6 */
|
||||
fn icmpv6_enabled(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn icmpv6_recv(&self, _p: &Icmpv6Packet, _c: &ClientInfo) {}
|
||||
fn icmpv6_drop(&self, _p: &Icmpv6Packet, _c: &ClientInfo) {}
|
||||
fn icmpv6_send(&self, _p: &MutableIcmpv6Packet, _c: &ClientInfo) {}
|
||||
/* TCP */
|
||||
fn tcp_enabled(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn tcp_recv(&self, _p: &TcpPacket, _c: &ClientInfo) {}
|
||||
fn tcp_drop(&self, _p: &TcpPacket, _c: &ClientInfo) {}
|
||||
fn tcp_send(&self, _p: &MutableTcpPacket, _c: &ClientInfo) {}
|
||||
/* UDP */
|
||||
fn udp_enabled(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn udp_recv(&self, _p: &UdpPacket, _c: &ClientInfo) {}
|
||||
fn udp_drop(&self, _p: &UdpPacket, _c: &ClientInfo) {}
|
||||
fn udp_send(&self, _p: &MutableUdpPacket, _c: &ClientInfo) {}
|
||||
}
|
|
@ -35,12 +35,14 @@ use pnet::{
|
|||
util::MacAddr,
|
||||
};
|
||||
|
||||
use crate::logger::{ConsoleLogger, MetaLogger};
|
||||
use crate::utils::IpAddrParser;
|
||||
|
||||
mod client;
|
||||
mod layer_2;
|
||||
mod layer_3;
|
||||
mod layer_4;
|
||||
mod logger;
|
||||
mod proto;
|
||||
mod smack;
|
||||
mod synackcookie;
|
||||
|
@ -55,6 +57,8 @@ pub struct Masscanned<'a> {
|
|||
/* iface is an Option to make tests easier */
|
||||
pub iface: Option<&'a NetworkInterface>,
|
||||
pub ip_addresses: Option<&'a HashSet<IpAddr>>,
|
||||
/* loggers */
|
||||
pub log: MetaLogger,
|
||||
}
|
||||
|
||||
/* Get the L2 network interface from its name */
|
||||
|
@ -184,14 +188,17 @@ fn main() {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
let masscanned = Masscanned {
|
||||
let mut masscanned = Masscanned {
|
||||
synack_key: [0, 0],
|
||||
mac,
|
||||
iface: Some(&iface),
|
||||
ip_addresses,
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
info!("interface......{}", masscanned.iface.unwrap().name);
|
||||
info!("mac address....{}", masscanned.mac);
|
||||
masscanned.log.add(Box::new(ConsoleLogger::new()));
|
||||
masscanned.log.init();
|
||||
let (mut tx, mut rx) = get_channel(masscanned.iface.unwrap());
|
||||
loop {
|
||||
/* check if network interface is still up */
|
||||
|
|
|
@ -165,6 +165,8 @@ mod tests {
|
|||
|
||||
use pnet::util::MacAddr;
|
||||
|
||||
use crate::logger::MetaLogger;
|
||||
|
||||
#[test]
|
||||
fn test_proto_dispatch_stun() {
|
||||
let mut client_info = ClientInfo::new();
|
||||
|
@ -180,6 +182,7 @@ mod tests {
|
|||
mac: MacAddr::from_str("00:11:22:33:44:55").expect("error parsing MAC address"),
|
||||
iface: None,
|
||||
ip_addresses: Some(&ips),
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
/***** TEST STUN - MAGIC *****/
|
||||
/* test payload is:
|
||||
|
@ -239,6 +242,7 @@ mod tests {
|
|||
mac: MacAddr::from_str("00:11:22:33:44:55").expect("error parsing MAC address"),
|
||||
iface: None,
|
||||
ip_addresses: Some(&ips),
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
/***** TEST SSH *****/
|
||||
let payloads = [
|
||||
|
@ -278,6 +282,7 @@ mod tests {
|
|||
mac: MacAddr::from_str("00:11:22:33:44:55").expect("error parsing MAC address"),
|
||||
iface: None,
|
||||
ip_addresses: Some(&ips),
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
/***** TEST GHOST *****/
|
||||
let payloads = [
|
||||
|
@ -310,6 +315,7 @@ mod tests {
|
|||
mac: MacAddr::from_str("00:11:22:33:44:55").expect("error parsing MAC address"),
|
||||
iface: None,
|
||||
ip_addresses: Some(&ips),
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
/***** TEST COMPLETE REQUEST *****/
|
||||
let payload = b"GET / HTTP/1.1\r\n\r\n";
|
||||
|
|
|
@ -413,6 +413,8 @@ mod tests {
|
|||
|
||||
use pnet::util::MacAddr;
|
||||
|
||||
use crate::logger::MetaLogger;
|
||||
|
||||
#[test]
|
||||
fn test_proto_stun_ipv4() {
|
||||
/* test payload is:
|
||||
|
@ -439,6 +441,7 @@ mod tests {
|
|||
mac: MacAddr::from_str("00:11:22:33:44:55").expect("error parsing MAC address"),
|
||||
iface: None,
|
||||
ip_addresses: Some(&ips),
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
let payload_resp = if let Some(r) = repl(payload, &masscanned, &mut client_info) {
|
||||
r
|
||||
|
@ -498,6 +501,7 @@ mod tests {
|
|||
mac: MacAddr::from_str("00:11:22:33:44:55").expect("error parsing MAC address"),
|
||||
iface: None,
|
||||
ip_addresses: Some(&ips),
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
client_info.ip.src = Some(IpAddr::V6(test_ip_addr));
|
||||
client_info.ip.dst = Some(IpAddr::V6(masscanned_ip_addr));
|
||||
|
@ -549,6 +553,7 @@ mod tests {
|
|||
mac: MacAddr::from_str("00:11:22:33:44:55").expect("error parsing MAC address"),
|
||||
iface: None,
|
||||
ip_addresses: Some(&ips),
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
client_info.ip.src = Some(IpAddr::V4(test_ip_addr));
|
||||
client_info.ip.dst = Some(IpAddr::V4(masscanned_ip_addr));
|
||||
|
@ -598,6 +603,7 @@ mod tests {
|
|||
mac: MacAddr::from_str("00:11:22:33:44:55").expect("error parsing MAC address"),
|
||||
iface: None,
|
||||
ip_addresses: Some(&ips),
|
||||
log: MetaLogger::new(),
|
||||
};
|
||||
client_info.ip.src = Some(IpAddr::V4(test_ip_addr));
|
||||
client_info.ip.dst = Some(IpAddr::V4(masscanned_ip_addr));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue