diff --git a/Cargo.lock b/Cargo.lock index 161d927..83566e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -262,8 +262,8 @@ dependencies = [ ] [[package]] -name = "p0f" -version = "0.1.0" +name = "passivetcp-rs" +version = "0.0.0" dependencies = [ "clap", "failure", diff --git a/Cargo.toml b/Cargo.toml index d50eb66..05f035a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,13 @@ [package] -name = "p0f" -version = "0.1.0" +name = "passivetcp-rs" edition = "2021" +description = "A Rust library for passive traffic fingerprinting [p0f]" +license = "MIT OR Apache-2.0" +authors = ["Your Name "] +repository = "https://github.com/biandratti/passivetcp-rs" +readme = "README.md" +keywords = ["p0f", "fingerprinting", "network", "security", "TCP"] +categories = ["network-programming"] [dependencies] nom = "7.1" @@ -11,3 +17,11 @@ regex = "1.11.1" failure = "0.1.8" log = "0.4.22" lazy_static = "1.5.0" + +[lib] +name = "passivetcp" +path = "src/lib.rs" + +[[example]] +name = "passive_scan" +path = "examples/passive_scan.rs" diff --git a/examples/passive_scan.rs b/examples/passive_scan.rs new file mode 100644 index 0000000..5a515a6 --- /dev/null +++ b/examples/passive_scan.rs @@ -0,0 +1,47 @@ +use passivetcp::{Database, P0fOutput, SignatureDetails, SignatureMatcher}; +use pnet::datalink::{self, Config, Channel::Ethernet}; + +fn main() { + let db = Database::default(); + let matcher = SignatureMatcher::new(&db); + + let interface_name = "eth0"; + let interfaces = datalink::interfaces(); + let interface = interfaces + .into_iter() + .find(|iface| iface.name == interface_name) + .expect("Could not find the interface"); + + let config = Config { + promiscuous: true, + ..Config::default() + }; + + // Set up the datalink channel + let (_tx, mut rx) = match datalink::channel(&interface, config) { + Ok(Ethernet(tx, rx)) => (tx, rx), + Ok(_) => panic!("Unhandled channel type"), + Err(e) => panic!("Unable to create channel: {}", e), + }; + + // Listen for packets and print passive scan output + loop { + match rx.next() { + Ok(packet) => { + if let Ok(signature_details) = SignatureDetails::extract(packet) { + if let Some((label, _)) = matcher.find_matching_signature(&signature_details.signature) { + let output = P0fOutput { + client: signature_details.client, + server: signature_details.server, + is_client: signature_details.is_client, + label: Some(label.clone()), + sig: signature_details.signature, + }; + println!("{}", output); + } + } + } + Err(e) => eprintln!("Failed to read packet: {}", e), + } + } +} \ No newline at end of file