| Crates.io | r-lanlib |
| lib.rs | r-lanlib |
| version | 0.1.5 |
| created_at | 2025-08-12 16:18:12.366438+00 |
| updated_at | 2025-08-14 17:03:19.348439+00 |
| description | A library crate for performing network scanning operations on any local area network (LAN) |
| homepage | https://github.com/robgonnella/r-lanscan |
| repository | https://github.com/robgonnella/r-lanscan |
| max_upload_size | |
| id | 1792203 |
| size | 148,899 |
A Rust library crate for performing network scanning operations on any local area network (LAN). This is the Rust version of the go-lanscan package.
cargo add r-lanlib
use std::{sync::mpsc, time::Duration};
use r_lanlib::{
network, packet,
scanners::{
arp_scanner::{ARPScanner, ARPScannerArgs},
Device, ScanMessage, Scanner,
},
targets::ips::IPTargets,
};
// Get default network interface
let interface = network::get_default_interface()
.expect("Cannot find network interface");
// Create packet wire (reader/sender)
let wire = packet::wire::default(&interface)
.expect("Failed to create packet wire");
// Define IP targets (scan entire subnet)
let ip_targets = IPTargets::new(vec![interface.cidr.clone()]);
// Create communication channel
let (tx, rx) = mpsc::channel::<ScanMessage>();
// Configure scanner
let scanner = ARPScanner::new(ARPScannerArgs {
interface: &interface,
packet_reader: wire.0,
packet_sender: wire.1,
targets: ip_targets,
source_port: 54321,
include_vendor: true,
include_host_names: true,
idle_timeout: Duration::from_millis(10000),
notifier: tx,
});
// Start scanning (runs in background thread)
let handle = scanner.scan();
// Process results in real-time
let mut devices = Vec::new();
loop {
match rx.recv().expect("Failed to receive message") {
ScanMessage::Done => break,
ScanMessage::ARPScanResult(device) => {
println!("Found device: {} ({})", device.ip, device.hostname);
devices.push(device);
}
ScanMessage::Info(scanning) => {
println!("Scanning: {}", scanning.ip);
}
}
}
handle.join().expect("Scanner thread failed");
println!("Discovered {} devices", devices.len());
use r_lanlib::{
scanners::{
syn_scanner::{SYNScanner, SYNScannerArgs},
Device, SYNScanResult, Scanner,
},
targets::ports::PortTargets,
};
// Define target devices (from previous ARP scan or manual)
let devices = vec![
Device {
hostname: "router".to_string(),
ip: "192.168.1.1".to_string(),
mac: "aa:bb:cc:dd:ee:ff".to_string(),
vendor: "".to_string(),
is_current_host: false,
}
];
// Define port targets
let port_targets = PortTargets::new(vec![
"22".to_string(), // SSH
"80".to_string(), // HTTP
"443".to_string(), // HTTPS
"8000-9000".to_string(), // Port range
]);
let scanner = SYNScanner::new(SYNScannerArgs {
interface: &interface,
packet_reader: wire.0,
packet_sender: wire.1,
targets: devices,
ports: port_targets,
source_port: 54321,
idle_timeout: Duration::from_millis(10000),
notifier: tx,
});
// Process SYN scan results
let mut results = Vec::new();
let handle = scanner.scan();
loop {
match rx.recv().expect("Failed to receive message") {
ScanMessage::Done => break,
ScanMessage::SYNScanResult(result) => {
println!("Open port {} on {}",
result.open_port.id,
result.device.ip
);
results.push(result);
}
_ => {}
}
}
use r_lanlib::scanners::{
full_scanner::{FullScanner, FullScannerArgs},
Scanner,
};
let scanner = FullScanner::new(FullScannerArgs {
interface: &interface,
packet_reader: wire.0,
packet_sender: wire.1,
targets: ip_targets,
ports: port_targets,
include_vendor: true,
include_host_names: true,
idle_timeout: Duration::from_millis(10000),
notifier: tx,
source_port: 54321,
});
// This will perform ARP discovery first, then SYN scan on found devices
let handle = scanner.scan();
networkProvides helpers for selecting network interfaces:
get_default_interface() - Get the default network interfaceget_interface(name) - Get a specific interface by nameget_available_port() - Find an available port for scanningpacketLow-level packet creation and transmission:
wire::default(interface) - Create default packet reader/sender pairscannersMain scanning implementations:
ARPScanner - Discover devices using ARPSYNScanner - Scan ports on known devicesFullScanner - Combined ARP + SYN scanningtargetsTarget specification utilities:
ips::IPTargets - Define IP ranges and CIDR blocksports::PortTargets - Define port ranges and individual portsDeviceRepresents a discovered network device:
pub struct Device {
pub hostname: String,
pub ip: String,
pub mac: String,
pub vendor: String,
pub is_current_host: bool,
}
PortRepresents a network port:
pub struct Port {
pub id: u16,
pub service: String,
}
SYNScanResultResult of a SYN scan operation:
pub struct SYNScanResult {
pub device: Device,
pub open_port: Port,
}
ScanMessageMessages sent over the notification channel:
pub enum ScanMessage {
Done, // Scanning complete
Info(Scanning), // Status update
ARPScanResult(Device), // ARP discovery result
SYNScanResult(SYNScanResult), // SYN scan result
}
// CIDR blocks
IPTargets::new(vec!["192.168.1.0/24".to_string()]);
// IP ranges
IPTargets::new(vec!["192.168.1.1-192.168.1.100".to_string()]);
// Individual IPs
IPTargets::new(vec!["192.168.1.1".to_string(), "10.0.0.1".to_string()]);
// Port ranges
PortTargets::new(vec!["1-1000".to_string()]);
// Individual ports
PortTargets::new(vec!["22".to_string(), "80".to_string(), "443".to_string()]);
// Mixed specification
PortTargets::new(vec![
"22".to_string(),
"80".to_string(),
"8000-9000".to_string()
]);
The library includes several complete examples in the examples/ directory:
arp-scanner.rs - Basic ARP device discoverysyn-scanner.rs - Port scanning on known devicesfull-scanner.rs - Complete network reconnaissanceRun examples from the workspace root with:
sudo -E cargo run --example arp-scanner -p r-lanlib
sudo -E cargo run --example syn-scanner -p r-lanlib
sudo -E cargo run --example full-scanner -p r-lanlib
idle_timeout - How long to wait for responses before concluding scaninclude_vendor - Perform MAC address vendor lookup using IEEE OUI databaseinclude_host_names - Resolve hostnames via reverse DNS lookupsource_port - Source port for scan packets (auto-selected if not specified)The library uses ScanError for comprehensive error reporting:
pub struct ScanError {
pub ip: Option<String>,
pub port: Option<String>,
pub error: Box<dyn Error>,
}
All scanner operations return Result<(), ScanError> for proper error handling.
This project is dual-licensed under either of
at your option.